diff --git a/oum.sh b/oum.sh
index 094608d..cc47093 100755
--- a/oum.sh
+++ b/oum.sh
@@ -1,572 +1,579 @@
-#!/usr/bin/env bash
-# Copyright Atomicorp 2021
-# AGPL 3.0
-# Authors:
-# - Charity Ponton
-# - Cody Woods
-# - Frank Iacovino
-# - Juliy V. Chirkov (@juliyvchirkov)
-# - Scott Shinn (@atomicturtle)
-
-
-# Globals
-VERSION=0.5
-OSSEC_HOME=/var/ossec
-SERVER=updates.atomicorp.com
-OSSEC_CRS_RULES_VERSION=0
-OSSEC_CRS_THREAT_VERSION=0
-OSSEC_CRS_RULES_VERSION_CURRENT=0
-OSSEC_CRS_THREAT_VERSION_CURRENT=0
-
-# Functions
-print_error() {
- local OPTIND
- local OPTARG
- local opt
- local xtranl
- local tab
- local prefix
-
- while getopts ":ltTp" opt
- do
- case ${opt} in
- l)
- xtranl='\n'
- ;;
- t)
- tab='\t'
- ;;
- T)
- tab='\t\t'
- ;;
- p)
- prefix='ERROR: '
- ;;
- esac
- done
-
- shift $((OPTIND - 1))
-
- >&2 printf "${xtranl}${tab}${prefix}%s\n${xtranl}" "${@}"
-}
-
-which() {
- local bindir
-
- for bindir in $(IFS=: && echo ${PATH})
- do
- [ -x ${bindir}/${1} ] && return 0
- done
-
- return 1
-}
-
-encode_uri_component() {
- [ $# -gt 0 ] && printf "${@}" | perl -pe 's/(.)/sprintf("%%%x", ord($1))/eg'
-}
-
-set_perm() {
- chown $(stat -c %U:%G ${OSSEC_HOME}) "${1}"
-
- if [ -d "${1}" ]
- then
- chmod 550 "${1}"
- else
- [[ ! $(stat -c %A "${1}") =~ x ]] && chmod 640 "${1}"
- fi
-}
-
-prereq_check() {
- local NOT_OK
- local -a PREREQS=("curl" "tar" "gzip" "bc" "grep" "sed" "perl" "mktemp" "chown" "chmod" "stat" "find" "cp" "rm" "mv")
- local PREREQ
-
- for PREREQ in "${PREREQS[@]}"
- do
- ! which ${PREREQ} && NOT_OK=1 && print_error -tp "${PREREQ} not found. ${PREREQ} must be installed."
- done
-
- [ ! -d ${OSSEC_HOME} ] && NOT_OK=1 && print_error -tp "OSSEC package not found. OSSEC must be installed."
-
- [ -n "${NOT_OK}" ] && print_error -l "Prerequisite check failed. Exiting!" && exit 1
-
- # Check for globbing
- if ! grep -q decoders.d ${OSSEC_HOME}/etc/ossec.conf
- then
- print_error
- print_error -t "WARNING: ${OSSEC_HOME}/etc/ossec.conf is not configured for decoders.d"
- print_error -t "replace the section with:"
- print_error
- print_error -t ""
- print_error -T 'etc/decoders.d'
- print_error -T 'etc/rules.d'
- print_error -T "etc/lists/threat
"
- print_error -t ""
- print_error
- fi
-}
-
-download() {
- local RETVAL
- local RESPONSE
- local -a OPTS
-
- [ -n "${DEBUG}" ] || OPTS+=("-s")
- [ -n "${INSECURE}" ] && OPTS+=("--insecure")
-
- RESPONSE=$(curl --write-out '%{http_code}' ${OPTS[@]} ${1} -o ${2})
- RETVAL=$?
-
- if [ ${RETVAL} -ne 0 ]
- then
- [ ${RETVAL} -eq 60 ] && print_error -ltp "Peer certificate cannot be authenticated with known CA certificates."
- print_error -lp "Download failed with ERROR (${RETVAL})"
- exit 1
- fi
-
- [ ${RESPONSE} -eq 401 ] && print_error -ltp "request returned HTTP error code 401 [Username/Password Invalid]" && exit 1
- [ ${RESPONSE} -ne 200 ] && print_error -ltp "request returned HTTP error code ${RESPONSE}" && exit 1
-
- set_perm ${2}
-}
-
-show_help() {
- printf '\n%s\n\n' "OSSEC Updater Modified (OUM) $VERSION"
- printf '%s\n\n' "Usage: oum [options] COMMAND"
- printf '\t%s\n\n' "List of commands:"
- printf '\t%s\t\t\t%s\n' "help" "Display this usage message"
- printf '\t%s\t\t\t%s\n' "list" "List pending updates"
- printf '\t%s\t\t\t%s\n' "update" "Update system"
- printf '\t%s\t\t%s\n' "configure" "Configure system"
- printf '\t%s\t%s\n' "install package-name" "Install package"
- printf '\t%s\t\t\t%s\n\n' "version" "Display version"
- printf '\t%s\n\n' "List of options:"
- printf '\t%s\t\t\t%s\n' "-y" "Automatic yes to prompts"
- printf '\t%s\t\t\t%s\n' "-d" "Debug mode"
- printf '\t%s\t\t\t%s\n\n' "-i" "Do not verify SSL"
-}
-
-load_config() {
- [ ! -f ${OSSEC_HOME}/etc/oum.conf ] && print_error -p "${OSSEC_HOME}/etc/oum.conf not found." && exit 1
-
- source ${OSSEC_HOME}/etc/oum.conf
-}
-
-check_version() {
- [ -f ${OSSEC_HOME}/tmp/VERSION ] && rm -f ${OSSEC_HOME}/tmp/VERSION
-
- download https://${SERVER}/channels/rules/VERSION ${OSSEC_HOME}/tmp/VERSION
-
- # Load old version
- if [ -f ${OSSEC_HOME}/var/VERSION ]
- then
- source ${OSSEC_HOME}/var/VERSION
-
- OSSEC_CRS_RULES_VERSION_CURRENT=${OSSEC_CRS_RULES_VERSION}
- OSSEC_CRS_THREAT_VERSION_CURRENT=${OSSEC_CRS_THREAT_VERSION}
- fi
-}
-
-update_version() {
- if [ ! -f ${OSSEC_HOME}/var/VERSION ]
- then
- echo "OSSEC_CRS_RULES_VERSION=0" >${OSSEC_HOME}/var/VERSION
- echo "OSSEC_CRS_THREAT_VERSION=0" >>${OSSEC_HOME}/var/VERSION
-
- set_perm ${OSSEC_HOME}/var/VERSION
- fi
-
- sed -i "s/${1}.*/${1}=${2}/g" ${OSSEC_HOME}/var/VERSION
-}
-
-show_updates() {
- local -a ARRAY1
- local idx
-
- check_version
-
- source ${OSSEC_HOME}/tmp/VERSION
-
- [ $(echo "${OSSEC_CRS_RULES_VERSION} > ${OSSEC_CRS_RULES_VERSION_CURRENT}" | bc -l) -eq 1 ] &&
- ARRAY1[0]="OSSEC-CRS-Rules ${OSSEC_CRS_RULES_VERSION}"
-
- [ ${OSSEC_CRS_THREAT_VERSION_CURRENT} -lt ${OSSEC_CRS_THREAT_VERSION} ] &&
- ARRAY1[1]="Atomicorp-Threatfeed ${OSSEC_CRS_THREAT_VERSION}"
-
- if [ ${#ARRAY1[@]} -gt 0 ]
- then
- printf '%s\n' "Updates available."
-
- for idx in ${!ARRAY1[@]}
- do
- [ ${idx} -eq 0 ] && printf "\t%s\t\t\t%s\n" ${ARRAY1[$idx]} || printf "\t%s\t\t%s\n" ${ARRAY1[$idx]}
- done
- else
- printf '%s\n' "No available updates."
- fi
-}
-
-update_rules() {
- local item
-
- printf '\t%s\n' "Downloading Rule update: ${OSSEC_CRS_RULES_VERSION}"
-
- download https://$(encode_uri_component ${USERNAME}):$(encode_uri_component ${PASSWORD})@${SERVER}/channels/rules/ossec/ossec-crs-rules-${OSSEC_CRS_RULES_VERSION}.tar.gz ${OSSEC_HOME}/tmp/ossec-crs-rules-${OSSEC_CRS_RULES_VERSION}.tar.gz
-
- pushd ${OSSEC_HOME}/tmp >/dev/null
-
- [ -d ossec-rules ] && rm -rf ossec-rules
-
- printf '\t%s ' "Extracting archive:"
-
- if tar xf ossec-crs-rules-${OSSEC_CRS_RULES_VERSION}.tar.gz
- then
- printf '%s\n' "OK"
- else
- printf '%s\n' "Failed"
- print_error -tp "archive could not be extracted"
- exit 1
- fi
-
- rm -f ossec-crs-rules-${OSSEC_CRS_RULES_VERSION}.tar.gz
-
- while IFS= read -r -d '' item
- do
- set_perm "${item}"
- done < <(find ${OSSEC_HOME}/tmp/ossec-rules -print0)
-
- # Back up rules
- printf '\t%s ' "Making backup of current rules:"
-
- [ -d ${OSSEC_HOME}/var/backup ] && rm -rf ${OSSEC_HOME}/var/backup
-
- for item in ${OSSEC_HOME}/var/backup ${OSSEC_HOME}/var/backup/decoders.d ${OSSEC_HOME}/var/backup/rules.d
- do
- mkdir ${item} && set_perm ${item}
- done
-
- [ -d ${OSSEC_HOME}/etc/decoders.d ] && cp -a ${OSSEC_HOME}/etc/decoders.d/* ${OSSEC_HOME}/var/backup/decoders.d/
-
- [ -d ${OSSEC_HOME}/etc/rules.d ] && cp -a ${OSSEC_HOME}/etc/rules.d/* ${OSSEC_HOME}/var/backup/rules.d/
-
- printf '%s\n' "OK"
-
- printf '\t%s ' "Applying base rule policy:"
-
- [ ! -d ${OSSEC_HOME}/etc/decoders.d ] && mkdir ${OSSEC_HOME}/etc/decoders.d && set_perm ${OSSEC_HOME}/etc/decoders.d
- rm -f ${OSSEC_HOME}/etc/decoders.d/*
- cp -a ossec-rules/decoders.d/* ${OSSEC_HOME}/etc/decoders.d/
-
- [ ! -d ${OSSEC_HOME}/etc/rules.d ] && mkdir ${OSSEC_HOME}/etc/rules.d && set_perm ${OSSEC_HOME}/etc/rules.d
- rm -f ${OSSEC_HOME}/etc/rules.d/*
- cp -a ossec-rules/rules.d/* ${OSSEC_HOME}/etc/rules.d/
-
- printf '%s\n' "OK"
-
- if [ -n "${EXCLUDE_RULES}" ]
- then
- # Exclude rules
- printf '\t%s\n' "Excluding rulesets."
-
- for item in ${EXCLUDE_RULES}
- do
- [ -f ${OSSEC_HOME}/etc/rules.d/${item} ] && printf '\t%s\n' "Disabling: ${item}" && rm -f ${OSSEC_HOME}/etc/rules.d/${item}
- done
- fi
-
- # Lint
- printf '\t%s ' "Verifying rules:"
-
- if ${OSSEC_HOME}/bin/ossec-analysisd -t >/dev/null 2>&1
- then
- printf '%s\n' "OK"
-
- # update version
- update_version OSSEC_CRS_RULES_VERSION ${OSSEC_CRS_RULES_VERSION}
- else
- printf '%s\n' "Failed"
- print_error -tp "Rule update failed lint"
-
- rm -f ${OSSEC_HOME}/etc/decoders.d/*
- rm -f ${OSSEC_HOME}/etc/rules.d/*
-
- printf '\t%s\n\n' "Reverting to last working copy"
-
- cp -a ${OSSEC_HOME}/var/backup/decoders.d/* ${OSSEC_HOME}/etc/decoders.d/
- cp -a ${OSSEC_HOME}/var/backup/rules.d/* ${OSSEC_HOME}/etc/decoders.d/
-
- exit 1
- fi
-
- # add string to update
- UPDATE_OUT+=("OSSEC CRS Rules ${OSSEC_CRS_RULES_VERSION}")
-
- # cleanup
- rm -rf ossec-rules
-
- popd >/dev/null
-}
-
-update_threatfeed() {
- local item
-
- printf '\t%s\n' "Downloading Atomicorp Threatfeed update: ${OSSEC_CRS_THREAT_VERSION}"
-
- download https://$(encode_uri_component ${USERNAME}):$(encode_uri_component ${PASSWORD})@${SERVER}/channels/rules/ossec/atomicorp-threatfeed-${OSSEC_CRS_THREAT_VERSION}.tar.gz ${OSSEC_HOME}/tmp/atomicorp-threatfeed-${OSSEC_CRS_THREAT_VERSION}.tar.gz
-
- pushd ${OSSEC_HOME}/tmp >/dev/null
-
- [ -d atomicorp-threatfeed ] && rm -rf atomicorp-threatfeed
-
- printf '\t%s ' "Extracting archive:"
-
- if tar xf atomicorp-threatfeed-${OSSEC_CRS_THREAT_VERSION}.tar.gz
- then
- printf '%s\n' "OK"
- else
- printf '%s\n' "Failed"
- print_error -tp "archive could not be extracted"
- exit 1
- fi
-
- rm -f atomicorp-threatfeed-${OSSEC_CRS_THREAT_VERSION}.tar.gz
-
- while IFS= read -r -d '' item
- do
- set_perm "${item}"
- done < <(find ${OSSEC_HOME}/tmp/atomicorp-threatfeed -print0)
-
- [ ! -d ${OSSEC_HOME}/etc/lists ] && mkdir ${OSSEC_HOME}/etc/lists && set_perm ${OSSEC_HOME}/etc/lists
- [ ! -d ${OSSEC_HOME}/etc/lists/threat ] && mkdir ${OSSEC_HOME}/etc/lists/threat && set_perm ${OSSEC_HOME}/etc/lists/threat
-
- rm -f ${OSSEC_HOME}/etc/lists/threat/*
-
- cp -a atomicorp-threatfeed/* ${OSSEC_HOME}/etc/lists/threat/
-
- # update version
- update_version OSSEC_CRS_THREAT_VERSION ${OSSEC_CRS_THREAT_VERSION}
-
- # add string to update
- UPDATE_OUT+=("Atomicorp Threatfeed ${OSSEC_CRS_THREAT_VERSION}")
-
- # cleanup
- rm -rf atomicorp-threatfeed
-
- popd >/dev/null
-}
-
-# Apply updates if they are available
-update() {
- local -a UPDATE_OUT
- local RESTART=""
- local -a ARRAY1
- local idx
-
- [[ -z "${USERNAME}" || "${USERNAME}" = "USERNAME" ]] && print_error -lp "oum credentials have not been configured. Run:\n\toum configure" && exit 1
-
- check_version
-
- source ${OSSEC_HOME}/tmp/VERSION
-
- [ ${DEBUG} ] && printf '%s\n' "DEBUG: Compare ${OSSEC_CRS_RULES_VERSION_CURRENT} to ${OSSEC_CRS_RULES_VERSION}"
-
- [ $(echo "${OSSEC_CRS_RULES_VERSION} > ${OSSEC_CRS_RULES_VERSION_CURRENT}" | bc -l) -eq 1 ] &&
- ARRAY1[0]="OSSEC-CRS-Rules ${OSSEC_CRS_RULES_VERSION}"
-
- [ ${OSSEC_CRS_THREAT_VERSION_CURRENT} -lt ${OSSEC_CRS_THREAT_VERSION} ] &&
- ARRAY1[1]="Atomicorp-Threatfeed ${OSSEC_CRS_THREAT_VERSION}"
-
- if [ ${#ARRAY1[@]} -gt 0 ]
- then
- printf '=%.0s' {1..79}
- printf '\n\t%s\t\t\t%s\n' "Component" "Version"
- printf '=%.0s' {1..79}
- printf '\n%s\n' "Upgrading:"
-
- for idx in ${!ARRAY1[@]}
- do
- [ ${idx} -eq 0 ] && printf "\t%s\t\t\t%s\n" ${ARRAY1[$idx]} || printf "\t%s\t\t%s\n" ${ARRAY1[$idx]}
- done
- printf '=%.0s' {1..79}
- printf '\n'
-
- if [ -z "${YES}" ]
- then
- read -rp "Is this ok [Y/N]: " -n1
-
- [[ ! ${REPLY} =~ ^[Yy]$ ]] && print_error -l "Operation aborted." && exit 1
- fi
-
- for idx in ${!ARRAY1[@]}
- do
- [[ ${ARRAY1[$idx]} =~ "OSSEC-CRS-Rules" ]] && update_rules
- [[ ${ARRAY1[$idx]} =~ "Atomicorp-Threatfeed" ]] && update_threatfeed
- done
-
- RESTART=1
-
- printf '\n%s\n' "Upgraded:"
-
- for idx in ${!UPDATE_OUT[@]}
- do
- printf '\t%s\n' "${UPDATE_OUT[$idx]}"
- done
-
- printf '%s\n\n' "Complete!"
- else
- printf '%s\n' "No packages marked for update."
- fi
-
- # Restart ossec
- if [ -n "${RESTART}" ]
- then
- printf '\t%s ' "Restarting OSSEC:"
-
- if [ -n "$DEBUG" ]
- then
- printf '\n'
- ${OSSEC_HOME}/bin/ossec-control restart
- else
- ${OSSEC_HOME}/bin/ossec-control restart >/dev/null 2>&1
- fi
-
- [ $? -eq 0 ] && printf '%s\n\n' "OK" || printf '%s\n\n' "Failed"
- fi
-}
-
-configure() {
- local conf_cur
- local conf_tmp
- local user_tmp
- local pass_tmp
-
- printf '\n%s\n' "OSSEC Updater Modified (OUM) ${VERSION}"
-
- conf_cur=$(mktemp -u -p $OSSEC_HOME/etc oum.XXXXXXXX.conf)
- conf_tmp=$(mktemp -u -p $OSSEC_HOME/etc oum.XXXXXXXX.conf)
-
- cp -a ${OSSEC_HOME}/etc/oum.conf ${conf_cur}
- cp -a ${conf_cur} ${conf_tmp}
-
- # Prompt for Username
- read -rp "Please enter your subscription username [Default: ] " user_tmp
-
- until [ -n "${user_tmp}" ]
- do
- print_error -ltp "Username cannot be blank."
-
- read -rp "Please enter your subscription username [Default: ] " user_tmp
- done
-
- sed -i '/USERNAME=.*/d' ${conf_cur}
-
- echo "USERNAME=$(printf %q "${user_tmp}")" >${conf_tmp}
-
- # Prompt for Password
- read -rsp "Please enter your subscription password [Default: ] " pass_tmp
-
- until [ -n "${pass_tmp}" ]
- do
- print_error -ltp "Password cannot be blank."
-
- read -rsp "Please enter your subscription password [Default: ] " pass_tmp
- done
-
- sed -i '/PASSWORD=.*/d' ${conf_cur}
-
- echo "PASSWORD=$(printf %q "${pass_tmp}")" >>${conf_tmp}
-
- cat ${conf_cur} >>${conf_tmp}
-
- rm -f ${conf_cur}
-
- mv -f ${conf_tmp} ${OSSEC_HOME}/etc/oum.conf
-
- printf '\n%s\n\n%s\n\t%s\n\n' "Configuration Complete!" "To update the system, please run:" "oum update"
-}
-
-# Installs a package via OUM
-install_package() {
- local PKG="unknown"
-
- [ -z "${1}" ] && print_error -p "package not specified. To install a package, please run:" && print_error -t "oum install package-name" && exit 1
-
- printf '\n%s\n\n' "Installing Package: ${1}"
-
- which yum && PKG="rpm"
- which apt-get && PKG="deb"
-
- if [ "${PKG}" = "rpm" ]
- then
- yum install -y --enablerepo=atomic ${1}
- elif [ "${PKG}" = "deb" ]
- then
- DEBIAN_FRONTEND=noninteractive apt-get -y install ${1}
- else
- print_error -lp "installation not supported."
-
- exit 1
- fi
-
- if [ $? ]
- then
- printf '\n\t%s\n\n' "${1} successfully installed."
- else
- print_error -ltp "There was a problem installing ${1}!"
-
- exit 1
- fi
-}
-
-while getopts ":ydi" opt
-do
- case ${opt} in
- y)
- YES=1
- ;;
- d)
- DEBUG=1
- ;;
- i)
- INSECURE=1
- ;;
- \?)
- print_error -ltp "invalid option -${OPTARG}" && show_help && exit 1
- ;;
- esac
-done
-
-shift $((OPTIND - 1))
-
-[ -n "${DEBUG}" ] && set -x
-
-# Load our config file
-load_config
-
-prereq_check
-
-# Command line arguments
-command=${1}
-
-shift
-
-case "${command}" in
- list)
- show_updates
- ;;
- configure)
- configure
- ;;
- update)
- update
- ;;
- install)
- install_package ${1}
- ;;
- version)
- printf '\n%s\n\n' "OUM Version: $VERSION"
- ;;
- *)
- show_help
- ;;
-esac
+#!/usr/bin/env bash
+# Copyright Atomicorp 2021
+# AGPL 3.0
+# Authors:
+# - Charity Ponton
+# - Cody Woods
+# - Frank Iacovino
+# - Juliy V. Chirkov (@juliyvchirkov)
+# - Scott Shinn (@atomicturtle)
+
+
+# Globals
+VERSION=0.5
+OSSEC_HOME=/var/ossec
+SERVER=updates.atomicorp.com
+OSSEC_CRS_RULES_VERSION=0
+OSSEC_CRS_THREAT_VERSION=0
+OSSEC_CRS_RULES_VERSION_CURRENT=0
+OSSEC_CRS_THREAT_VERSION_CURRENT=0
+
+# Functions
+print_error() {
+ local OPTIND
+ local OPTARG
+ local opt
+ local xtranl
+ local tab
+ local prefix
+
+ while getopts ":ltTp" opt
+ do
+ case ${opt} in
+ l)
+ xtranl='\n'
+ ;;
+ t)
+ tab='\t'
+ ;;
+ T)
+ tab='\t\t'
+ ;;
+ p)
+ prefix='ERROR: '
+ ;;
+ esac
+ done
+
+ shift $((OPTIND - 1))
+
+ >&2 printf "${xtranl}${tab}${prefix}%s\n${xtranl}" "${@}"
+}
+
+which() {
+ local bindir
+
+ for bindir in $(IFS=: && echo ${PATH})
+ do
+ [ -x ${bindir}/${1} ] && return 0
+ done
+
+ return 1
+}
+
+encode_uri_component() {
+ [ $# -gt 0 ] && printf "${@}" | perl -pe 's/(.)/sprintf("%%%x", ord($1))/eg'
+}
+
+set_perm() {
+ chown $(stat -c %U:%G ${OSSEC_HOME}) "${1}"
+
+ if [ -d "${1}" ]
+ then
+ chmod 550 "${1}"
+ else
+ [[ ! $(stat -c %A "${1}") =~ x ]] && chmod 640 "${1}"
+ fi
+}
+
+prereq_check() {
+ local NOT_OK
+ local -a PREREQS=("curl" "tar" "gzip" "bc" "grep" "sed" "perl" "mktemp" "chown" "chmod" "stat" "find" "cp" "rm" "mv")
+ local PREREQ
+
+ for PREREQ in "${PREREQS[@]}"
+ do
+ ! which ${PREREQ} && NOT_OK=1 && print_error -tp "${PREREQ} not found. ${PREREQ} must be installed."
+ done
+
+ [ ! -d ${OSSEC_HOME} ] && NOT_OK=1 && print_error -tp "OSSEC package not found. OSSEC must be installed."
+
+ [ -n "${NOT_OK}" ] && print_error -l "Prerequisite check failed. Exiting!" && exit 1
+
+ # Check for globbing
+ if ! grep -q decoders.d ${OSSEC_HOME}/etc/ossec.conf
+ then
+ print_error
+ print_error -t "WARNING: ${OSSEC_HOME}/etc/ossec.conf is not configured for decoders.d"
+ print_error -t "replace the section with:"
+ print_error
+ print_error -t ""
+ print_error -T 'etc/decoders.d'
+ print_error -T 'etc/rules.d'
+ print_error -T "etc/lists/threat
"
+ print_error -t ""
+ print_error
+ fi
+}
+
+download() {
+ local RETVAL
+ local RESPONSE
+ local -a OPTS
+
+ [ -n "${DEBUG}" ] || OPTS+=("-s")
+ [ -n "${INSECURE}" ] && OPTS+=("--insecure")
+
+ RESPONSE=$(curl --write-out '%{http_code}' ${OPTS[@]} ${1} -o ${2})
+ RETVAL=$?
+
+ if [ ${RETVAL} -ne 0 ]
+ then
+ [ ${RETVAL} -eq 60 ] && print_error -ltp "Peer certificate cannot be authenticated with known CA certificates."
+ print_error -lp "Download failed with ERROR (${RETVAL})"
+ exit 1
+ fi
+
+ [ ${RESPONSE} -eq 401 ] && print_error -ltp "request returned HTTP error code 401 [Username/Password Invalid]" && exit 1
+ [ ${RESPONSE} -ne 200 ] && print_error -ltp "request returned HTTP error code ${RESPONSE}" && exit 1
+
+ set_perm ${2}
+}
+
+show_help() {
+ printf '\n%s\n\n' "OSSEC Updater Modified (OUM) $VERSION"
+ printf '%s\n\n' "Usage: oum [options] COMMAND"
+ printf '\t%s\n\n' "List of commands:"
+ printf '\t%s\t\t\t%s\n' "help" "Display this usage message"
+ printf '\t%s\t\t\t%s\n' "list" "List pending updates"
+ printf '\t%s\t\t\t%s\n' "update" "Update system"
+ printf '\t%s\t\t%s\n' "configure" "Configure system"
+ printf '\t%s\t%s\n' "install package-name" "Install package"
+ printf '\t%s\t\t\t%s\n\n' "version" "Display version"
+ printf '\t%s\n\n' "List of options:"
+ printf '\t%s\t\t\t%s\n' "-y" "Automatic yes to prompts"
+ printf '\t%s\t\t\t%s\n' "-d" "Debug mode"
+ printf '\t%s\t\t\t%s\n\n' "-i" "Do not verify SSL"
+}
+
+load_config() {
+ [ ! -f ${OSSEC_HOME}/etc/oum.conf ] && print_error -p "${OSSEC_HOME}/etc/oum.conf not found." && exit 1
+
+ source ${OSSEC_HOME}/etc/oum.conf
+}
+
+check_version() {
+ [ -f ${OSSEC_HOME}/tmp/VERSION ] && rm -f ${OSSEC_HOME}/tmp/VERSION
+
+ download https://${SERVER}/channels/rules/VERSION ${OSSEC_HOME}/tmp/VERSION
+
+ # Load old version
+ if [ -f ${OSSEC_HOME}/var/VERSION ]
+ then
+ source ${OSSEC_HOME}/var/VERSION
+
+ OSSEC_CRS_RULES_VERSION_CURRENT=${OSSEC_CRS_RULES_VERSION}
+ OSSEC_CRS_THREAT_VERSION_CURRENT=${OSSEC_CRS_THREAT_VERSION}
+ fi
+}
+
+update_version() {
+ if [ ! -f ${OSSEC_HOME}/var/VERSION ]
+ then
+ echo "OSSEC_CRS_RULES_VERSION=0" >${OSSEC_HOME}/var/VERSION
+ echo "OSSEC_CRS_THREAT_VERSION=0" >>${OSSEC_HOME}/var/VERSION
+
+ set_perm ${OSSEC_HOME}/var/VERSION
+ fi
+
+ sed -i "s/${1}.*/${1}=${2}/g" ${OSSEC_HOME}/var/VERSION
+}
+
+show_updates() {
+ local -a ARRAY1
+ local idx
+
+ check_version
+
+ source ${OSSEC_HOME}/tmp/VERSION
+
+ [ $(echo "${OSSEC_CRS_RULES_VERSION} > ${OSSEC_CRS_RULES_VERSION_CURRENT}" | bc -l) -eq 1 ] &&
+ ARRAY1[0]="OSSEC-CRS-Rules ${OSSEC_CRS_RULES_VERSION}"
+
+ [ ${OSSEC_CRS_THREAT_VERSION_CURRENT} -lt ${OSSEC_CRS_THREAT_VERSION} ] &&
+ ARRAY1[1]="Atomicorp-Threatfeed ${OSSEC_CRS_THREAT_VERSION}"
+
+ if [ ${#ARRAY1[@]} -gt 0 ]
+ then
+ printf '%s\n' "Updates available."
+
+ for idx in ${!ARRAY1[@]}
+ do
+ [ ${idx} -eq 0 ] && printf "\t%s\t\t\t%s\n" ${ARRAY1[$idx]} || printf "\t%s\t\t%s\n" ${ARRAY1[$idx]}
+ done
+ else
+ printf '%s\n' "No available updates."
+ fi
+}
+
+update_rules() {
+ local item
+
+ printf '\n\t%s\n' "Downloading Rule update: ${OSSEC_CRS_RULES_VERSION}"
+
+ download https://$(encode_uri_component ${USERNAME}):$(encode_uri_component ${PASSWORD})@${SERVER}/channels/rules/ossec/ossec-crs-rules-${OSSEC_CRS_RULES_VERSION}.tar.gz ${OSSEC_HOME}/tmp/ossec-crs-rules-${OSSEC_CRS_RULES_VERSION}.tar.gz
+
+ pushd ${OSSEC_HOME}/tmp >/dev/null
+
+ [ -d ossec-rules ] && rm -rf ossec-rules
+
+ printf '\t%s ' "Extracting archive:"
+
+ if tar xf ossec-crs-rules-${OSSEC_CRS_RULES_VERSION}.tar.gz
+ then
+ printf '%s\n' "OK"
+ else
+ printf '%s\n' "Failed"
+ print_error -tp "archive could not be extracted"
+ exit 1
+ fi
+
+ rm -f ossec-crs-rules-${OSSEC_CRS_RULES_VERSION}.tar.gz
+
+ while IFS= read -r -d '' item
+ do
+ set_perm "${item}"
+ done < <(find ${OSSEC_HOME}/tmp/ossec-rules -print0)
+
+ # Back up rules
+ printf '\t%s ' "Making backup of current rules:"
+
+ [ -d ${OSSEC_HOME}/var/backup ] && rm -rf ${OSSEC_HOME}/var/backup
+
+ for item in ${OSSEC_HOME}/var/backup ${OSSEC_HOME}/var/backup/decoders.d ${OSSEC_HOME}/var/backup/rules.d
+ do
+ mkdir ${item} && set_perm ${item}
+ done
+
+ [ -d ${OSSEC_HOME}/etc/decoders.d ] && cp -a ${OSSEC_HOME}/etc/decoders.d/* ${OSSEC_HOME}/var/backup/decoders.d/
+
+ [ -d ${OSSEC_HOME}/etc/rules.d ] && cp -a ${OSSEC_HOME}/etc/rules.d/* ${OSSEC_HOME}/var/backup/rules.d/
+
+ printf '%s\n' "OK"
+
+ printf '\t%s ' "Applying base rule policy:"
+
+ [ ! -d ${OSSEC_HOME}/etc/decoders.d ] && mkdir ${OSSEC_HOME}/etc/decoders.d && set_perm ${OSSEC_HOME}/etc/decoders.d
+ rm -f ${OSSEC_HOME}/etc/decoders.d/*
+ cp -a ossec-rules/decoders.d/* ${OSSEC_HOME}/etc/decoders.d/
+
+ [ ! -d ${OSSEC_HOME}/etc/rules.d ] && mkdir ${OSSEC_HOME}/etc/rules.d && set_perm ${OSSEC_HOME}/etc/rules.d
+ rm -f ${OSSEC_HOME}/etc/rules.d/*
+ cp -a ossec-rules/rules.d/* ${OSSEC_HOME}/etc/rules.d/
+
+ printf '%s\n' "OK"
+
+ if [ -n "${EXCLUDE_RULES}" ]
+ then
+ # Exclude rules
+ printf '\t%s\n' "Excluding rulesets."
+
+ for item in ${EXCLUDE_RULES}
+ do
+ [ -f ${OSSEC_HOME}/etc/rules.d/${item} ] && printf '\t%s\n' "Disabling: ${item}" && rm -f ${OSSEC_HOME}/etc/rules.d/${item}
+ done
+ fi
+
+ # Lint
+ printf '\t%s ' "Verifying rules:"
+
+ if ${OSSEC_HOME}/bin/ossec-analysisd -t >/dev/null 2>&1
+ then
+ printf '%s\n' "OK"
+
+ # update version
+ update_version OSSEC_CRS_RULES_VERSION ${OSSEC_CRS_RULES_VERSION}
+ else
+ printf '%s\n' "Failed"
+ print_error -tp "Rule update failed lint"
+
+ rm -f ${OSSEC_HOME}/etc/decoders.d/*
+ rm -f ${OSSEC_HOME}/etc/rules.d/*
+
+ printf '\t%s\n\n' "Reverting to last working copy"
+
+ cp -a ${OSSEC_HOME}/var/backup/decoders.d/* ${OSSEC_HOME}/etc/decoders.d/
+ cp -a ${OSSEC_HOME}/var/backup/rules.d/* ${OSSEC_HOME}/etc/decoders.d/
+
+ exit 1
+ fi
+
+ # add string to update
+ UPDATE_OUT+=("OSSEC CRS Rules ${OSSEC_CRS_RULES_VERSION}")
+
+ # cleanup
+ rm -rf ossec-rules
+
+ popd >/dev/null
+}
+
+update_threatfeed() {
+ local item
+
+ printf '\n\t%s\n' "Downloading Atomicorp Threatfeed update: ${OSSEC_CRS_THREAT_VERSION}"
+
+ download https://$(encode_uri_component ${USERNAME}):$(encode_uri_component ${PASSWORD})@${SERVER}/channels/rules/ossec/atomicorp-threatfeed-${OSSEC_CRS_THREAT_VERSION}.tar.gz ${OSSEC_HOME}/tmp/atomicorp-threatfeed-${OSSEC_CRS_THREAT_VERSION}.tar.gz
+
+ pushd ${OSSEC_HOME}/tmp >/dev/null
+
+ [ -d atomicorp-threatfeed ] && rm -rf atomicorp-threatfeed
+
+ printf '\t%s ' "Extracting archive:"
+
+ if tar xf atomicorp-threatfeed-${OSSEC_CRS_THREAT_VERSION}.tar.gz
+ then
+ printf '%s\n' "OK"
+ else
+ printf '%s\n' "Failed"
+ print_error -tp "archive could not be extracted"
+ exit 1
+ fi
+
+ rm -f atomicorp-threatfeed-${OSSEC_CRS_THREAT_VERSION}.tar.gz
+
+ while IFS= read -r -d '' item
+ do
+ set_perm "${item}"
+ done < <(find ${OSSEC_HOME}/tmp/atomicorp-threatfeed -print0)
+
+ [ ! -d ${OSSEC_HOME}/etc/lists ] && mkdir ${OSSEC_HOME}/etc/lists && set_perm ${OSSEC_HOME}/etc/lists
+ [ ! -d ${OSSEC_HOME}/etc/lists/threat ] && mkdir ${OSSEC_HOME}/etc/lists/threat && set_perm ${OSSEC_HOME}/etc/lists/threat
+
+ rm -f ${OSSEC_HOME}/etc/lists/threat/*
+
+ cp -a atomicorp-threatfeed/* ${OSSEC_HOME}/etc/lists/threat/
+
+ # update version
+ update_version OSSEC_CRS_THREAT_VERSION ${OSSEC_CRS_THREAT_VERSION}
+
+ # add string to update
+ UPDATE_OUT+=("Atomicorp Threatfeed ${OSSEC_CRS_THREAT_VERSION}")
+
+ # cleanup
+ rm -rf atomicorp-threatfeed
+
+ popd >/dev/null
+}
+
+# Apply updates if they are available
+update() {
+ local -a UPDATE_OUT
+ local RESTART=""
+ local -a ARRAY1
+ local idx
+
+ [[ -z "${USERNAME}" || "${USERNAME}" = "USERNAME" ]] && print_error -lp "oum credentials have not been configured. Run:\n\toum configure" && exit 1
+
+ check_version
+
+ source ${OSSEC_HOME}/tmp/VERSION
+
+ [ ${DEBUG} ] && printf '%s\n' "DEBUG: Compare ${OSSEC_CRS_RULES_VERSION_CURRENT} to ${OSSEC_CRS_RULES_VERSION}"
+
+ [ $(echo "${OSSEC_CRS_RULES_VERSION} > ${OSSEC_CRS_RULES_VERSION_CURRENT}" | bc -l) -eq 1 ] &&
+ ARRAY1[0]="OSSEC-CRS-Rules ${OSSEC_CRS_RULES_VERSION}"
+
+ [ ${OSSEC_CRS_THREAT_VERSION_CURRENT} -lt ${OSSEC_CRS_THREAT_VERSION} ] &&
+ ARRAY1[1]="Atomicorp-Threatfeed ${OSSEC_CRS_THREAT_VERSION}"
+
+ if [ ${#ARRAY1[@]} -gt 0 ]
+ then
+ printf '=%.0s' {1..79}
+ printf '\n\t%s\t\t\t%s\n' "Component" "Version"
+ printf '=%.0s' {1..79}
+ printf '\n%s\n' "Upgrading:"
+
+ for idx in ${!ARRAY1[@]}
+ do
+ [ ${idx} -eq 0 ] && printf "\t%s\t\t\t%s\n" ${ARRAY1[$idx]} || printf "\t%s\t\t%s\n" ${ARRAY1[$idx]}
+ done
+ printf '=%.0s' {1..79}
+ printf '\n'
+
+ if [ -z "${YES}" ]
+ then
+ read -rp "Is this ok [Y/N]: " -n1
+
+ [[ ! ${REPLY} =~ ^[Yy]$ ]] && print_error -l "Operation aborted." && exit 1
+ fi
+
+ for idx in ${!ARRAY1[@]}
+ do
+ [[ ${ARRAY1[$idx]} =~ "OSSEC-CRS-Rules" ]] && update_rules
+ [[ ${ARRAY1[$idx]} =~ "Atomicorp-Threatfeed" ]] && update_threatfeed
+ done
+
+ RESTART=1
+
+ printf '\n%s\n' "Upgraded:"
+
+ for idx in ${!UPDATE_OUT[@]}
+ do
+ printf '\t%s\n' "${UPDATE_OUT[$idx]}"
+ done
+
+ printf '%s\n\n' "Complete!"
+ else
+ printf '%s\n' "No packages marked for update."
+ fi
+
+ # Restart ossec
+ if [ -n "${RESTART}" ]
+ then
+ printf '\t%s ' "Restarting OSSEC:"
+
+ if [ -n "$DEBUG" ]
+ then
+ printf '\n'
+ ${OSSEC_HOME}/bin/ossec-control restart
+ else
+ ${OSSEC_HOME}/bin/ossec-control restart >/dev/null 2>&1
+ fi
+
+ [ $? -eq 0 ] && printf '%s\n\n' "OK" || printf '%s\n\n' "Failed"
+ fi
+}
+
+configure() {
+ local conf_cur
+ local conf_tmp
+ local user_tmp
+ local pass_tmp
+
+ printf '\n%s\n' "OSSEC Updater Modified (OUM) ${VERSION}"
+
+ conf_cur=$(mktemp -u -p $OSSEC_HOME/etc oum.XXXXXXXX.conf)
+ conf_tmp=$(mktemp -u -p $OSSEC_HOME/etc oum.XXXXXXXX.conf)
+
+ cp -a ${OSSEC_HOME}/etc/oum.conf ${conf_cur}
+ cp -a ${conf_cur} ${conf_tmp}
+
+ # Prompt for Username
+ read -rp "Please enter your subscription username [Default: ${USERNAME}]: " user_tmp
+
+ if [[ ${USERNAME} ]] && [[ $user_tmp == "" ]]; then
+ user_tmp=${USERNAME}
+ fi
+
+ until [ -n "${user_tmp}" ]; do
+ print_error -ltp "Username cannot be blank."
+
+ read -rp "Please enter your subscription username [Default: ${USERNAME}]: " user_tmp
+ done
+
+ sed -i '/USERNAME=.*/d' ${conf_cur}
+
+ echo "USERNAME=$(printf %q "${user_tmp}")" >${conf_tmp}
+
+ # Prompt for Password
+ read -rsp "Please enter your subscription password [Default: ${PASSWORD}] " pass_tmp
+
+ if [[ ${PASSWORD} ]] && [[ $pass_tmp == "" ]]; then
+ pass_tmp=${PASSWORD}
+ fi
+
+ until [ -n "${pass_tmp}" ]; do
+ print_error -ltp "Password cannot be blank."
+
+ read -rsp "Please enter your subscription password [Default: ${PASSWORD}] " pass_tmp
+ done
+
+ sed -i '/PASSWORD=.*/d' ${conf_cur}
+
+ echo "PASSWORD=$(printf %q "${pass_tmp}")" >>${conf_tmp}
+
+ cat ${conf_cur} >>${conf_tmp}
+
+ rm -f ${conf_cur}
+
+ mv -f ${conf_tmp} ${OSSEC_HOME}/etc/oum.conf
+
+ printf '\n%s\n\n%s\n\t%s\n\n' "Configuration Complete!" "To update the system, please run:" "oum update"
+}
+
+# Installs a package via OUM
+install_package() {
+ local PKG="unknown"
+
+ [ -z "${1}" ] && print_error -p "package not specified. To install a package, please run:" && print_error -t "oum install package-name" && exit 1
+
+ printf '\n%s\n\n' "Installing Package: ${1}"
+
+ which yum && PKG="rpm"
+ which apt-get && PKG="deb"
+
+ if [ "${PKG}" = "rpm" ]
+ then
+ yum install -y --enablerepo=atomic ${1}
+ elif [ "${PKG}" = "deb" ]
+ then
+ DEBIAN_FRONTEND=noninteractive apt-get -y install ${1}
+ else
+ print_error -lp "installation not supported."
+
+ exit 1
+ fi
+
+ if [ $? ]
+ then
+ printf '\n\t%s\n\n' "${1} successfully installed."
+ else
+ print_error -ltp "There was a problem installing ${1}!"
+
+ exit 1
+ fi
+}
+
+while getopts ":ydi" opt
+do
+ case ${opt} in
+ y)
+ YES=1
+ ;;
+ d)
+ DEBUG=1
+ ;;
+ i)
+ INSECURE=1
+ ;;
+ \?)
+ print_error -ltp "invalid option -${OPTARG}" && show_help && exit 1
+ ;;
+ esac
+done
+
+shift $((OPTIND - 1))
+
+[ -n "${DEBUG}" ] && set -x
+
+# Load our config file
+load_config
+
+prereq_check
+
+# Command line arguments
+command=${1}
+
+shift
+
+case "${command}" in
+ list)
+ show_updates
+ ;;
+ configure)
+ configure
+ ;;
+ update)
+ update
+ ;;
+ install)
+ install_package ${1}
+ ;;
+ version)
+ printf '\n%s\n' "OSSEC Updater Modified (OUM) Version: $VERSION"
+ printf '%s\n\n' " Copyright Atomicorp, Inc. 2021"
+ ;;
+ *)
+ show_help
+ ;;
+esac