#!/bin/bash

# 2018-07-31 Cornelius Koelbel <cornelius.koelbel@netknights.it>
#
# Copyright (c) 2018, Cornelius Koelbel
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

if [[ $(id -u) != 0 ]]; then
  echo "Script must be run as root user"
  exit 1
fi

PICFG="/etc/privacyidea/pi.cfg"

if [ "$#" -gt 0 ]; then
	PICFG=$1
fi

if [[ ! -r $PICFG ]];then
	echo "Could not read $PICFG! Please specify the pi.cfg file!"
	exit 1
fi

OS=$(grep "^ID=" /etc/os-release | sed -e 's/^ID=//g' | tr -d '"')
diag_info=$(mktemp -d -t pi_diag_XXXXXXXXXX)
tempfile="${diag_info}/privacyidea.config"
timestamp=$(date +"%y-%m-%d")
diag_file="/tmp/${timestamp}_$(basename "$diag_info").tar.gz"

case $OS in
	centos | rhel | debian | ubuntu)
	;;
	*)
		echo  "Your operating system $OS is not supported!"
		;;
esac

log() {
	echo "$1" >> "$tempfile"
}

call_pi_manage() {
	PRIVACYIDEA_CONFIGFILE=$PICFG pi-manage "$@"
}

upload_info() {
	echo
	echo "Please upload the diagnostics file $diag_file to your support team."
	echo
}

get_os() {
	log
	log "SECTION: Linux Distribution"
	log "==========================="
	cat /etc/*-release >> "$tempfile"
}

get_pi_cfg() {
	log
	log "SECTION: pi.cfg file"
	log "===================="
	grep -v -e 'SECRET_KEY\|PI_PEPPER\|SQLALCHEMY_DATABASE_URI' "$PICFG" >> "$tempfile"
	# only write the driver part of the URI to the logfile.
	# So we see if eg. pymysql, mysql or any other dialect is used.
	grep ^SQLALCHEMY_DATABASE_URI "$PICFG" | cut -d':' -f 1 >> "$tempfile"
}

current_db_revision() {
	log
	log "SECTION: current_db_revision"
	log "============================"
	call_pi_manage db current -d /opt/privacyidea/lib/privacyidea/migrations/ >> "$tempfile"
}

pi_versions() {
	log
	log "SECTION: privacyIDEA Versions"
	log "============================="
	log "Installed packages"
	log "------------------"
	FileName=$(mktemp)
	if [[ "${OS}" == "centos" || "${OS}" == "rhel" ]]; then
		# In case it is CentOS/RHEL
		rpm -qa | sort >> "$FileName"
	elif [[ "${OS}" == "ubuntu" || "${OS}" == "debian" ]]; then
		# In case it is Ubuntu/Debian
		dpkg -l | sort >> "$FileName";
	fi
	# save all installed packages
	cat "$FileName" >> "$tempfile"
	rm -f "$FileName"
	log
	log "Python packages in /opt/privacyidea:"
	log "===================================="
	if [[ -x  /opt/privacyidea/bin/pip ]]; then
		/opt/privacyidea/bin/pip freeze >> "$tempfile"
	fi
}

pi_config() {
	log
	log "SECTION: privacyIDEA Configuration"
	log "=================================="
	log "Resolvers"
	log "---------"
	call_pi_manage resolver list -v >> "$tempfile"
	log "Realms"
	log "------"
	call_pi_manage realm list >> "$tempfile"
	log "Events"
	log "------"
	call_pi_manage event e_export >> "$tempfile"
	log "Policies"
	log "--------"
	call_pi_manage policy p_export >> "$tempfile"
}

server_config() {
	# Extract configurations for smtp, privacyIDEA and RADIUS server
  server_config=$(call_pi_manage config exporter -t smtpserver privacyideaserver radiusserver -f json)

  log
  log "SECTION: SMTP|privacyIDEA|RADIUS Server Configuration"
	log "====================================================="
	log "$server_config"
}

FreeRADIUS_config() {
	log
	log "SECTION: FreeRADIUS Configurations"
	log "=================================="
	if [[ "${OS}" == "centos" || "${OS}" == "rhel" ]]; then
		if (rpm -qa | grep freeradius > /dev/null); then
			ls -R /etc/raddb  >> "$tempfile";
		else
			log
			log "FreeRADIUS is not installed"
		fi
	elif [[ "${OS}" == "ubuntu" || "${OS}" == "debian" ]]; then
		if (dpkg -l | grep freeradius > /dev/null); then
			ls -R /etc//freeradius/3.0 >> "$tempfile";
		else
			log
			log "FreeRADIUS is not installed"
		fi
	fi
}

system_status() {
	log
	log "SECTION: System Status"
	log "======================"
	log "CPU cores: $(grep -c ^processor /proc/cpuinfo)"
	log "========================"
	top -b -n 1 >> "$tempfile"
	log
	log "HD"
	log "========================"
	df -h >> "$tempfile"
}

centos_auditlog() {
	if [[ "$(getenforce)" == "Enforcing" ]]; then
		log
		log "SECTION: centOS Auditlog"
		log "========================"
		grep "denied" /var/log/audit/audit.log  >> "$tempfile"
	fi
}

apache_log() {
	if [[ "${OS}" == "centos" || "${OS}" == "rhel" ]]; then
		log
		log "SECTION: httpd SSL_error_log"
		log "============================"
		tail -100 /var/log/httpd/ssl_error_log  >> "$tempfile"
		log
		log "SECTION: httpd Access_log"
		log "========================="
		tail -100 /var/log/httpd/ssl_access_log  >> "$tempfile"
		log
		log "SECTION: apache configuration"
		log "============================="
		tail -n +1 /etc/httpd/conf/httpd.conf /etc/httpd/conf.d/privacyidea.conf >>  "$tempfile"
	elif [[ "${OS}" == "ubuntu" || "${OS}" == "debian" ]]; then
		log
		log "SECTION: apache2 error_log"
		log "=========================="
		tail -100 /var/log/apache2/error.log >> "$tempfile"
		log
		log "SECTION: apache2 SSL_access_log"
		log "==============================="
		tail -100 /var/log/apache2/ssl_access.log >> "$tempfile"
		log
		log "SECTION: apache configuration"
		log "============================="
		tail -n +1 /etc/apache2/apache2.conf /etc/apache2/sites-enabled/* >> "$tempfile"
	fi
}

ngnix_log(){
	# Check if NGNIX logs exist
	if [ -f /var/log/nginx/error.log ] && [ -f /var/log/nginx/access.log ]; then
		log
		log "SECTION: NGNIX-ERROR.LOG"
		log "========================"
		tail -n 100 /var/log/nginx/error.log >> "$tempfile"
		log
		log "SECTION: NGNIX-ACCESS.LOG"
		log "========================"
		tail -n 100 /var/log/nginx/access.log >> "$tempfile"
	fi
}

pi_logfile() {
	R=$( grep "^PI_LOGFILE" "$PICFG" | cut -d "=" -f2 | tr -d "\t \'\"" )
	[ -f ${R} ] && cp ${R} "${diag_info}/privacyidea.logfile" || echo "Could not read logfile ${R}" >> "$tempfile"
}

pi_auditlog() {
	call_pi_manage audit dump -f - -t 2d >> "${diag_info}/privacyidea.auditlog"
}

get_os
get_pi_cfg
current_db_revision
pi_versions
pi_config
server_config
FreeRADIUS_config
system_status
if [[ "${OS}" == "centos" ]]; then
	centos_auditlog
fi
apache_log
ngnix_log
pi_logfile
pi_auditlog

tar -zcf "$diag_file" -C /tmp "$(basename "$diag_info")"

upload_info
