diff --git a/detector.sh b/detector.sh new file mode 100755 index 0000000000000000000000000000000000000000..4d032b6cd00d07a17c9d37fc03c4c5d21ad2a432 --- /dev/null +++ b/detector.sh @@ -0,0 +1,156 @@ +#!/bin/bash +# ==================================================================== +# +# P O C * Detect a database type +# +# -------------------------------------------------------------------- +# ah: <www.axel-hahn.de> +# 2024-02-xx v0.1 ah Initial version +# -------------------------------------------------------------------- + +cd $( dirname $0 ) + +. jobhelper.sh || exit 1 +. vendor/ini.class.sh || exit 1 + +DBD_BASEDIR=plugins/localdump/profiles/ +declare -A DBD_PARAMS +DBD_DEBUG=0 + +# -------------------------------------------------------------------- +# +# -------------------------------------------------------------------- + +# ---------- GETTER + +function dbdetect._wd(){ + test "$DBD_DEBUG" -eq "1" && echo "DEBUG: $*" +} + +function dbdetect.getConfigs(){ + find ${DBD_BASEDIR} -type f -name "*.ini" +} + +function dbdetect.getType(){ + basename "$1" | cut -d "_" -f 1 | sed "s,\.ini$,," +} +function dbdetect.getProfile(){ + basename "$1" | cut -d "_" -f 1- | sed "s,\.ini$,," +} + + +function dbdetect.exists(){ + local _config="$1" + + DBD_PARAMS= + + local _found=0 + + # set file and inisection we read values from + ini.set "$_config" "detect" + + # --- check tcp + local tcpport; tcpport=$( ini.value "tcp" ) + local tcptarget; tcptarget=$( ini.value "tcp-target" ) + if { ! >/dev/tcp/$tcptarget/$tcpport; } > /dev/null 2>&1; then + # echo "No port tcp $tcpport available" + dbdetect._wd "... No port tcp $tcpport available on $tcptarget" + return 1 + fi + dbdetect._wd "... Found tcp $tcpport on $tcptarget." + + # --- check tcp process + local tcpprocess; tcpprocess=$( ini.value "tcp-process" ) + if [ -n "$tcpprocess" ]; then + if ! netstat -tulpen 2>/dev/null | grep "^tcp.*:${tcpport} .*/${tcpprocess}" >/dev/null; then + # echo "No port tcp $tcpport available" + dbdetect._wd "... $tcpprocess not found for tcp ${tcpport}" + return 1 + fi + dbdetect._wd "... tcp $tcpport is used by $tcpprocess." + fi + + # --- check binaries + local binary; binary=$( ini.value "binary" ) + if [ -n "${binary}" ]; then + for mybinary in $( echo "${binary}" | tr "," " " ); do + if ! j_requireBinary "$mybinary" 1 >/dev/null 2>&1; then + dbdetect._wd "... Missing binary: ${mybinary}" + return 1 + fi + dbdetect._wd "... Binary: ${mybinary} was found" + done + fi + + # --- check process + local process; process=$( ini.value "process" ) + if [ -n "${process}" ]; then + if ! j_requireProcess "${process}" 1 >/dev/null; then + dbdetect._wd "... Missing process: ${process}" + return 1 + fi + # if ! ps -eo command | grep -E "${process}" >/dev/null 2>&1; then + # dbdetect._wd "... Process ${process} was not found" + # return 1 + # fi + dbdetect._wd "... Process ${process} was found" + fi + + ini.set "$config" "set" + local value + local dbuser=$( ini.value "dbuser" ) + local dbpassword=$( ini.value "dbpassword" ) + + for mykey in $( ini.keys ) + do + # params = '--port={{tcp}} --password={{dbpassword}} --user={{dbuser}} --host={{tcp-target}}' + value="$( ini.value "$mykey" )" + value="${value//\{\{tcp\}\}/$tcpport}" + value="${value//\{\{tcp-target\}\}/$tcptarget}" + value="${value//\{\{dbuser\}\}/$dbuser}" + value="${value//\{\{dbpassword\}\}/$dbpassword}" + DBD_PARAMS[$mykey]="$value" + done + + return 0 +} + + +function dbdetect.getParams(){ + echo "${DBD_PARAMS['params']}" +} + +function dbdetect.runas(){ + echo "${DBD_PARAMS['su']}" +} + +# ---------------------------------------------------------------------- +# MAIN +# ---------------------------------------------------------------------- + +echo +echo " --==##| POC * DATABASE DETECTOR |##==-- " +echo + +dbdetect._wd +dbdetect._wd "------" + +dbdetect._wd ">>>>>>>>>> $module" +for config in $(dbdetect.getConfigs); do + dbdetect._wd "----- $config" + if dbdetect.exists $config; then + echo "FOUND: $config" + + echo " Type : $( dbdetect.getType $config )" + echo " Target dir : $( dbdetect.getProfile $config )" + echo " runas : $( dbdetect.runas )" + echo " Params : $( dbdetect.getParams )" + echo + else + echo "SKIP : $config" + fi + dbdetect._wd +done +echo + +# -------------------------------------------------------------------- diff --git a/plugins/localdump/profiles/mysql.ini b/plugins/localdump/profiles/mysql.ini new file mode 100644 index 0000000000000000000000000000000000000000..058f461ea27a324301c3ad2ac584f7c4369f1f39 --- /dev/null +++ b/plugins/localdump/profiles/mysql.ini @@ -0,0 +1,34 @@ +# ---------------------------------------------------------------------- +# what to detect +# ---------------------------------------------------------------------- + +[detect] +# binaries that must befound, comma seperated +binary = 'mysql,mysqldump' + +# a running process that must be found +process = 'mysqld|mariadb' + +# a port that must be open on a given host +tcp = 3306 +tcp-target = localhost + +# process that opens a port (see netstat -tulpen) - works for local services only +# "slirp4netns" is docker network stack +# "rootlesskit" is docker too +tcp-process = 'mysqld|mariadbd' + +# ---------------------------------------------------------------------- +# data to apply if it was found +# ---------------------------------------------------------------------- + +[set] + +su = '' +dbuser = 'root' +dbpassword = '12345678' + +# unschön - das ist in der Prozessliste +params = '--port={{tcp}} --password={{dbpassword}} --user={{dbuser}} --host={{tcp-target}}' + +# ---------------------------------------------------------------------- diff --git a/vendor/ini.class.sh b/vendor/ini.class.sh new file mode 100644 index 0000000000000000000000000000000000000000..845b6eb297d4e3ca50018841676dba94e4de81c3 --- /dev/null +++ b/vendor/ini.class.sh @@ -0,0 +1,110 @@ +#!/bin/bash +# ====================================================================== +# +# READ INI FILE with Bash +# https://axel-hahn.de/blog/2018/06/08/bash-ini-dateien-parsen-lesen/ +# +# ---------------------------------------------------------------------- +# 2024-02-04 v0.1 Initial version +# ====================================================================== + +INI_FILE= +INI_SECTION= + +# ---------------------------------------------------------------------- +# SETTER +# ---------------------------------------------------------------------- + +# Set the INI file - and optional section - for short calls. +# param string filename +# param string optional: section +function ini.set(){ + INI_FILE= + INI_SECTION= + if [ ! -f "$1" ]; then + echo "ERROR: file does not exist: $1" + exit 1 + fi + INI_FILE="$1" + + test -n "$2" && ini.setsection "$2" + +} + +# Set the INI section for short calls. +# param string section +function ini.setsection(){ + if [ -z "$INI_FILE" ]; then + echo "ERROR: ini file needs to be set first. Use ini.set <FILE> [<SECTION>]." + exit 1 + fi + if [ -n "$1" ]; then + if ini.sections "$INI_FILE" | grep "^${1}$" >/dev/null; then + INI_SECTION=$1 + else + echo "ERROR: Section [$1] does not exist in [$INI_FILE]." + exit 1 + fi + fi +} + +# ---------------------------------------------------------------------- +# GETTER +# ---------------------------------------------------------------------- + +# Get all sections +# param1 - name of the ini file +function ini.sections(){ + local myfile=$1 + grep "^\[" "$myfile" | sed 's,^\[,,' | sed 's,\].*,,' +} + +# Get all content inside a section +# param1 - name of the ini file +# param2 - name of the section in ini file +function ini.section(){ + local myfile=$1 + local mysection=$2 + sed -e "0,/^\[${mysection}\]/ d" -e '/^\[/,$ d' $myfile | grep -v "^[#;]" +} + +# Get all keys inside a section +# param1 - name of the ini file +# param2 - name of the section in ini file +function ini.keys(){ + local myfile=$1 + local mysection=$2 + + test -z "$myfile" && myfile=$INI_FILE + test -z "$mysection" && mysection=$INI_SECTION + + ini.section "${myfile}" "${mysection}" \ + | grep "^[\ \t]*[^=]" \ + | cut -f 1 -d "=" +} + + +# Get a value of a variable in a given section +# param1 - name of the ini file +# param2 - name of the section in ini file +# param3 - name of the variable to read +function ini.value(){ + + if [ -n "$2" ] && [ -z "$3" ]; then + ini.value "$INI_FILE" "$1" "$2" + elif [ -z "$2" ]; then + ini.value "$INI_FILE" "$INI_SECTION" "$1" + else + local myfile=$1 + local mysection=$2 + local myvarname=$3 + ini.section "${myfile}" "${mysection}" \ + | grep "^[\ \t]*${myvarname}[\ \t]*=.*" \ + | cut -f 2- -d "=" \ + | sed -e 's,^\ *,,' -e 's, *$,,' \ + -e 's,^",,g' -e 's,"$,,g' \ + -e "s,^',,g" -e "s,'$,,g" + fi +} + +# ----------------------------------------------------------------------