2 ################################################################################
3 # This is property of eXtremeSHOK.com
4 # You are free to use, modify and distribute, however you may not remove this notice.
5 # Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
6 ################################################################################
8 # Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
10 # Originially based on:
11 # Script provide by Bill Landry (unofficialsigs@gmail.com).
13 # License: BSD (Berkeley Software Distribution)
15 ################################################################################
17 # THERE ARE NO USER CONFIGURABLE OPTIONS IN THIS SCRIPT
18 # ALL CONFIGURATION OPTIONS ARE LOCATED IN THE INCLUDED CONFIGURATION FILE
20 ################################################################################
22 ################################################################################
24 ###### ####### # # ####### ####### ####### ###### ### #######
25 # # # # ## # # # # # # # # #
26 # # # # # # # # # # # # # # #
27 # # # # # # # # # # ##### # # # #
28 # # # # # # # # # # # # # # #
29 # # # # # ## # # # # # # # #
30 ###### ####### # # ####### # ####### ###### ### #
32 ################################################################################
34 # Detect to make sure the entire script is avilable, fail if the script is missing contents
35 if [ ! "$( tail -1 "$0" | head -1 | cut -c1-7 )" == "exit \$?" ] ; then
36 echo "FATAL ERROR: Script is incomplete, please redownload"
40 # trap the keyboard interrupt (ctrl+c)
41 trap xshok_control_c SIGINT
43 ################################################################################
45 ################################################################################
47 # Function to support user config settings for applying file and directory access permissions.
49 if [ -n "$clam_user" ] && [ -n "$clam_group" ] ; then
54 # Function to prompt a user if they should complete an action with Y or N
55 # usage: xshok_prompt_confirm
56 # if xshok_prompt_confirm; then
57 # xshok_prompt_confirm && echo "accepted"
58 # xshok_prompt_confirm && echo "yes" || echo "no"
59 function xshok_prompt_confirm () { #optional_message
60 message="${1:-Are you sure?}"
62 read -r -p "$message [y/N]" response </dev/tty
66 *) printf " \033[31m %s \n\033[0m" "invalid input"
71 # Function to create a pid file
72 function xshok_create_pid_file { #pid.file
76 if [ $? -ne 0 ] ; then
77 xshok_pretty_echo_and_log "ERROR: Could not create PID file: $pidfile"
81 xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
86 # Function to intercept ctrl+c and calls the cleanup function
87 function xshok_control_c () {
89 xshok_pretty_echo_and_log "--------------| Exiting ... Please wait |--------------" "-"
95 function xshok_cleanup () {
96 #wait for all processes to end
98 xshok_pretty_echo_and_log " Powered By https://eXtremeSHOK.com " "#"
102 # Function to check if the current running user is the root user, otherwise return false
103 function xshok_is_root () {
104 if [ "$(uname -s)" = "SunOS" ] ; then
105 id_bin="/usr/xpg4/bin/id"
109 if [ "$($id_bin -u)" = 0 ] ; then
116 # Function to check if its a file, otherwise return false
117 function xshok_is_file () { #"filepath"
119 if [ -f "${filepath}" ] ; then
122 return 1 ; #not a file
126 # Function to check if filepath is a subdir, otherwise return false
127 # Usage: xshok_is_subdir "filepath"
128 # xshok_is_subdir "/root/" - false
129 # xshok_is_subdir "/usr/local/etc" && echo "yes" - yes
130 function xshok_is_subdir () { #filepath
131 filepath=$(echo "$1" | sed 's:/*$::')
132 if [ -d "$filepath" ] ; then
133 res="${filepath//[^\/]}"
134 if [ "${#res}" -gt 1 ] ; then
137 return 1 ; #not a subdir
140 return 1 ; #not a dir
144 # Function to create a dir and set the ownership
145 function xshok_mkdir_ownership () { #"path"
147 mkdir -p "$1" 2>/dev/null
148 if [ $? -ne 0 ] ; then
149 xshok_pretty_echo_and_log "ERROR: Could not create directory: $1"
152 perms chown -f "$clam_user:$clam_group" "$1" > /dev/null 2>&1
154 xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
159 # Function to check if a user and group exists on the system otherwise return false
161 # xshok_is_subdir "username" && echo "user found" || echo "no"
162 # xshok_is_subdir "username" "groupname" && echo "user and group found" || echo "no"
163 function xshok_user_group_exists () { #"username" "groupname"
164 if [ "$(uname -s)" = "SunOS" ] ; then
165 id_bin="/usr/xpg4/bin/id"
170 $id_bin -u "$1" > /dev/null 2>&1
171 if [ $? -eq 0 ]; then
173 $id_bin -g "$2" > /dev/null 2>&1
174 if [ $? -eq 0 ]; then
175 return 0 ; #user and group exists
177 return 1 ; #group does NOT exist
180 return 0 ; #user exists
183 return 1 ; #user does NOT exist
186 xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
191 # Function to handle comments with/out borders and logging.
193 # pretty_echo_and_log "one"
195 # pretty_echo_and_log "two" "-"
199 # pretty_echo_and_log "three" "=" "8"
203 # pretty_echo_and_log "" "/\" "7"
205 #type: e = error, w= warning ""
206 function xshok_pretty_echo_and_log () { #"string" "repeating" "count" "type"
208 if [ "$comment_silence" = "no" ] ; then
209 if [ "${#@}" = "1" ] ; then
213 if [ -n "$3" ] ; then
218 for (( n = 0; n < mycount; n++ )) ; do
221 if [ "$1" != "" ] ; then
222 echo -e "$myvar\n$1\n$myvar"
230 if [ "$enable_log" == "yes" ] ; then
231 if [ ! -e "$log_file_path/$log_file_name" ] ; then
232 #xshok_mkdir_ownership "$log_file_path"
233 mkdir -p "$log_file_path"
234 touch "$log_file_path/$log_file_name" 2>/dev/null
235 perms chown -f "$clam_user:$clam_group" "$log_file_path/$log_file_name"
237 if [ ! -w "$log_file_path/$log_file_name" ] ; then
238 echo "Warning: Logging Disabled, as file not writable: $log_file_path/$log_file_name"
241 echo "$(date "+%b %d %T")" "$1" >> "$log_file_path/$log_file_name"
246 # function to check if the $2 value is not null and does not start with -
247 function xshok_check_s2 () { #value1 #value2
249 if [[ "$1" =~ ^-.* ]] ; then
250 xshok_pretty_echo_and_log "ERROR: Missing value for option or value begins with -" "="
254 xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
259 # function to count array elements and output the total element count
260 # required due to compound array assignment
262 # array=("one" "two" "three")
263 # xshok_array_count $array
265 function xshok_array_count () { #array
267 if [ -n "${k_array[*]}" ] ; then
269 for k in "${k_array[@]}" ; do
277 # function to auto update
278 function xshok_auto_update() { #version
279 xshok_pretty_echo_and_log "Performing automatic update..."
281 # Download new version
282 echo -n "Downloading latest version..."
283 if ! wget --quiet --output-document="$0.tmp" $UPDATE_BASE/$SELF ; then
284 echo "Failed: Error while trying to wget new version!"
285 echo "File requested: $UPDATE_BASE/$SELF"
290 # Copy over modes from old version
291 OCTAL_MODE=$(stat -c '%a' $SELF)
292 if ! chmod $OCTAL_MODE "$0.tmp" ; then
293 echo "Failed: Error while trying to set mode on $0.tmp."
297 # Generate the update script
298 cat > xshok_update_script.sh << EOF
300 # Overwrite old file with new
301 if mv "$0.tmp" "$0"; then
302 echo "Done. Update complete."
305 echo "Failed! The update was not completed."
310 echo -n "Inserting update process..."
312 #replaced with $0, so code will update and then call itself with the same parameters it had
313 #exec /bin/bash xshok_update_script.sh
317 #function to handle list of database files
318 function clamav_files () {
319 echo "$clam_dbs/$db" >> "$current_tmp"
320 if [ "$keep_db_backup" = "yes" ] ; then
321 echo "$clam_dbs/$db-bak" >> "$current_tmp"
325 # Function to manage the databases and allow multi-dimensions as well as global overrides
326 # since the datbases are basically a multi-dimentional associative arrays in bash
327 # ratings: LOW| MEDIUM| HIGH| REQUIRED| LOWONLY| MEDIUMONLY| LOWMEDIUMONLY | MEDIUMHIGHONLY | HIGHONLY| DISABLED
328 function xshok_database () { #database #rating
336 if [ -n "$current_dbs" ] ; then
337 if [ "$(xshok_array_count "$current_dbs")" -ge "1" ] ; then
338 for db_name in $current_dbs ; do
340 if [ "$enable_yararules" == "no" ] ; then #yararules are disabled
341 if [[ "$db_name" = *".yar"* ]] ; then # if it's the value you want to delete
342 continue # skip to the next value
345 if [ "$current_rating" == "" ] ; then #yararules are disabled
346 new_dbs="$new_dbs $db_name"
348 if [[ ! "$db_name" = *"|"* ]] ; then # this old format
349 new_dbs="$new_dbs $db_name"
351 db_name_rating=$(echo "$db_name" | cut -d "|" -f2)
352 db_name=$(echo "$db_name" | cut -d "|" -f1)
354 if [ "$db_name_rating" != "DISABLED" ] ; then
355 if [ "$db_name_rating" == "$current_rating" ] ; then
356 new_dbs="$new_dbs $db_name"
357 elif [ "$db_name_rating" == "REQUIRED" ] ; then
358 new_dbs="$new_dbs $db_name"
359 elif [ "$current_rating" == "LOW" ] ; then
360 if [ "$db_name_rating" == "LOWONLY" ] || [ "$db_name_rating" == "LOW" ] || [ "$db_name_rating" == "LOWMEDIUM" ] ; then
361 new_dbs="$new_dbs $db_name"
363 elif [ "$current_rating" == "MEDIUM" ] ; then
364 if [ "$db_name_rating" == "MEDIUMONLY" ] || [ "$db_name_rating" == "MEDIUM" ] || [ "$db_name_rating" == "LOW" ] || [ "$db_name_rating" == "LOWMEDIUM" ] ; then
365 new_dbs="$new_dbs $db_name"
367 elif [ "$current_rating" == "HIGH" ] ; then
368 if [ "$db_name_rating" == "HIGH" ] || [ "$db_name_rating" == "MEDIUM" ] || [ "$db_name_rating" == "LOW" ] ; then
369 new_dbs="$new_dbs $db_name"
378 echo "$new_dbs" | xargs #remove extra whitespace
382 ################################################################################
383 # ADDITIONAL PROGRAM FUNCTIONS
384 ################################################################################
387 #generates a man config and installs it
388 function install_man () {
390 if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
391 echo "This script (clamav-unofficial-sigs) was installed on the system via '$pkg_mgr'"
397 echo "Generating man file for install...."
399 #Use defined varibles or attempt to use default varibles
401 if [ ! -e "$man_dir/$man_filename" ] ; then
403 touch "$man_dir/$man_filename" 2>/dev/null
405 if [ ! -w "$man_dir/$man_filename" ] ; then
406 echo "ERROR: man install aborted, as file not writable: $man_dir/$man_filename"
412 manresult=$(help_and_usage "man")
415 cat << EOF > "$man_dir/$man_filename"
417 .\" Manual page for eXtremeSHOK.com ClamAV Unofficial Signature Updater
418 .TH clamav-unofficial-sigs 8 "$script_version_date" "Version: $script_version" "SCRIPT COMMANDS"
420 clamav-unofficial-sigs \- Download, test, and install third-party ClamAV signature databases.
422 .B clamav-unofficial-sigs
425 \fBclamav-unofficial-sigs\fP provides a simple way to download, test, and update third-party signature databases provided by Sanesecurity, FOXHOLE, OITC, Scamnailer, BOFHLAND, CRDF, Porcupine, Securiteinfo, MalwarePatrol, Yara-Rules Project, etc. It will also generate and install cron, logrotate, and man files.
427 Script updates can be found at: \fBhttps://github.com/extremeshok/clamav-unofficial-sigs\fP
429 This script follows the standard GNU command line syntax.
436 Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
438 You are free to use, modify and distribute, however you may not remove this notice.
440 BSD (Berkeley Software Distribution)
442 Report bugs to \fBhttps://github.com/extremeshok/clamav-unofficial-sigs\fP
444 Adrian Jon Kriel :: admin@extremeshok.com
445 Originially based on Script provide by Bill Landry
451 echo "Completed: man installed, as file: $man_dir/$man_filename"
455 #generates a logrotate config and installs it
456 function install_logrotate () {
458 if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
459 echo "This script (clamav-unofficial-sigs) was installed on the system via '$pkg_mgr'"
464 echo "Generating logrotate file for install...."
466 #Use defined varibles or attempt to use default varibles
468 if [ ! -n "$logrotate_user" ] ; then
469 logrotate_user="$clam_user";
471 if [ ! -n "$logrotate_group" ] ; then
472 logrotate_group="$clam_group";
474 if [ ! -n "$logrotate_log_file_full_path" ] ; then
475 logrotate_log_file_full_path="$log_file_path/$log_file_name"
479 if [ ! -e "$logrotate_dir/$logrotate_filename" ] ; then
480 mkdir -p "$logrotate_dir"
481 touch "$logrotate_dir/$logrotate_filename" 2>/dev/null
483 if [ ! -w "$logrotate_dir/$logrotate_filename" ] ; then
484 echo "ERROR: logrotate install aborted, as file not writable: $logrotate_dir/$logrotate_filename"
487 cat << EOF > "$logrotate_dir/$logrotate_filename"
488 # https://eXtremeSHOK.com ######################################################
489 # This file contains the logrotate settings for clamav-unofficial-sigs.sh
491 # This is property of eXtremeSHOK.com
492 # You are free to use, modify and distribute, however you may not remove this notice.
493 # Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
496 # Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
498 # Originially based on:
499 # Script provide by Bill Landry (unofficialsigs@gmail.com).
501 # License: BSD (Berkeley Software Distribution)
504 # Automatically Generated: $(date)
507 # This logrotate file will rotate the logs generated by the clamav-unofficial-sigs.sh
509 # To Adjust the logrotate values, edit your configs and run
510 # bash clamav-unofficial-sigs.sh --install-logrotate to generate a new file.
512 $logrotate_log_file_full_path {
518 create 0644 $logrotate_user $logrotate_group
524 echo "Completed: logrotate installed, as file: $logrotate_dir/$logrotate_filename"
527 #generates a cron config and installs it
528 function install_cron () {
530 if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
531 echo "This script (clamav-unofficial-sigs) was installed on the system via '$pkg_mgr'"
536 echo "Generating cron file for install...."
538 #Use defined varibles or attempt to use default varibles
539 if [ ! -n "$cron_minute" ] ; then
540 cron_minute=$(( ( RANDOM % 59 ) + 1 ));
542 if [ ! -n "$cron_user" ] ; then
543 cron_user="$clam_user";
545 if [ ! -n "$cron_bash" ] ; then
546 cron_bash=$(which bash)
548 if [ ! -n "$cron_script_full_path" ] ; then
549 cron_script_full_path="$this_script_full_path"
552 if [ ! -e "$cron_dir/$cron_filename" ] ; then
554 touch "$cron_dir/$cron_filename" 2>/dev/null
556 if [ ! -w "$cron_dir/$cron_filename" ] ; then
557 echo "ERROR: cron install aborted, as file not writable: $cron_dir/$cron_filename"
560 cat << EOF > "$cron_dir/$cron_filename"
561 # https://eXtremeSHOK.com ######################################################
562 # This file contains the cron settings for clamav-unofficial-sigs.sh
564 # This is property of eXtremeSHOK.com
565 # You are free to use, modify and distribute, however you may not remove this notice.
566 # Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
569 # Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
571 # Originially based on:
572 # Script provide by Bill Landry (unofficialsigs@gmail.com).
574 # License: BSD (Berkeley Software Distribution)
577 # Automatically Generated: $(date)
580 # This cron file will execute the clamav-unofficial-sigs.sh script that
581 # currently supports updating third-party signature databases provided
582 # by Sanesecurity, SecuriteInfo, MalwarePatrol, OITC, etc.
584 # The script is set to run hourly, at a random minute past the hour, and the
585 # script itself is set to randomize the actual execution time between
586 # 60 - 600 seconds. To Adjust the cron values, edit your configs and run
587 # bash clamav-unofficial-sigs.sh --install-cron to generate a new file.
589 $cron_minute * * * * $cron_user [ -x $cron_script_full_path ] && $cron_bash $cron_script_full_path > /dev/null
591 # https://eXtremeSHOK.com ######################################################
596 echo "Completed: cron installed, as file: $cron_dir/$cron_filename"
600 #decode a third-party signature either by signature name
601 function decode_third_party_signature_by_signature_name () {
603 echo "Input a third-party signature name to decode (e.g: Sanesecurity.Junk.15248) or"
604 echo "a hexadecimal encoded data string and press enter (do not include '.UNOFFICIAL'"
605 echo "in the signature name nor add quote marks to any input string):"
607 input=$(echo "$input" | tr -d "'" | tr -d '"')
608 if echo "$input" | $grep_bin "\." > /dev/null ; then
609 cd "$clam_dbs" || exit
610 sig=$($grep_bin "$input:" ./*.ndb)
611 if [ -n "$sig" ] ; then
612 db_file=$(echo "$sig" | cut -d ':' -f1)
613 echo "$input found in: $db_file"
614 echo "$input signature decodes to:"
615 echo "$sig" | cut -d ":" -f5 | perl -pe 's/([a-fA-F0-9]{2})|(\{[^}]*\}|\([^)]*\))/defined $2 ? $2 : chr(hex $1)/eg'
617 echo "Signature '$input' could not be found."
618 echo "This script will only decode ClamAV 'UNOFFICIAL' third-Party,"
619 echo "non-image based, signatures as found in the *.ndb databases."
622 echo "Here is the decoded hexadecimal input string:"
623 echo "$input" | perl -pe 's/([a-fA-F0-9]{2})|(\{[^}]*\}|\([^)]*\))/defined $2 ? $2 : chr(hex $1)/eg'
627 #Hexadecimal encode an entire input string
628 function hexadecimal_encode_entire_input_string () {
630 echo "Input the data string that you want to hexadecimal encode and then press enter. Do not include"
631 echo "any quotes around the string unless you want them included in the hexadecimal encoded output:"
633 echo "Here is the hexadecimal encoded input string:"
634 echo "$input" | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg'
637 #Hexadecimal encode a formatted input string
638 function hexadecimal_encode_formatted_input_string () {
640 echo "Input a formated data string containing spacing fields '{}, (), *' that you want to hexadecimal"
641 echo "encode, without encoding the spacing fields, and then press enter. Do not include any quotes"
642 echo "around the string unless you want them included in the hexadecimal encoded output:"
644 echo "Here is the hexadecimal encoded input string:"
645 echo "$input" | perl -pe 's/(\{[^}]*\}|\([^)]*\)|\*)|(.)/defined $1 ? $1 : sprintf("%02lx", ord $2)/eg'
648 #GPG verify a specific Sanesecurity database file
649 function gpg_verify_specific_sanesecurity_database_file () { #databasefile
652 db_file=$(echo "$1" | awk -F '/' '{print $NF}')
653 if [ -r "$work_dir_sanesecurity/$db_file" ] ; then
654 echo "GPG signature testing database file: $work_dir_sanesecurity/$db_file"
655 if [ -r "$work_dir_sanesecurity/$db_file".sig ] ; then
656 "$gpg_bin" -q --trust-model always --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg"/ss-keyring.gpg --verify "$work_dir_sanesecurity"/"$db_file".sig "$work_dir_sanesecurity"/"$db_file"
657 if [ "$?" != "0" ]; then
658 "$gpg_bin" -q --always-trust --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg"/ss-keyring.gpg --verify "$work_dir_sanesecurity"/"$db_file".sig "$work_dir_sanesecurity"/"$db_file"
659 if [ "$?" == "0" ]; then
668 echo "Signature '$db_file.sig' cannot be found."
671 echo "File '$db_file' cannot be found or is not a Sanesecurity database file."
672 echo "Only the following Sanesecurity and OITC databases can be GPG signature tested:"
673 ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_sanesecurity"
676 xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
681 #Output system and configuration information
682 function output_system_configuration_information () {
684 echo "*** SCRIPT VERSION ***"
685 echo "$this_script_name $script_version ($script_version_date)"
686 echo "*** SYSTEM INFORMATION ***"
688 echo "*** CLAMSCAN LOCATION & VERSION ***"
690 $clamscan_bin --version | head -1
691 echo "*** RSYNC LOCATION & VERSION ***"
693 $rsync_bin --version | head -1
694 if [ "$wget_bin" != "" ] ; then
695 echo "*** WGET LOCATION & VERSION ***"
697 $wget_bin --version | head -1
699 echo "*** CURL LOCATION & VERSION ***"
701 $curl_bin --version | head -1
703 echo "*** GPG LOCATION & VERSION ***"
705 $gpg_bin --version | head -1
706 echo "*** SCRIPT WORKING DIRECTORY INFORMATION ***"
708 echo "*** CLAMAV DIRECTORY INFORMATION ***"
710 echo "*** SCRIPT CONFIGURATION SETTINGS ***"
711 if [ "$custom_config" != "no" ] ; then
712 if [ -d "$custom_config" ] ; then
713 # Assign the custom config dir and remove trailing / (removes / and //)
714 echo "Custom Configuration Directory: $config_dir"
716 echo "Custom Configuration File: $custom_config"
719 echo "Configuration Directory: $config_dir"
723 #Make a signature database from an ascii file
724 function make_signature_database_from_ascii_file () {
727 The '-m' script flag provides a way to create a ClamAV hexadecimal signature database (*.ndb) file
728 from a list of data strings stored in a clear-text ascii file, with one data string entry per line.
730 - Hexadecimal encoding can be either 'full' or 'formatted' on a per line basis:
732 Full line encoding should be used if there are no formatted spacing entries [{}, (), *]
733 included on the line. Prefix unformatted lines with: '-:' (no quote marks).
737 -:This signature contains no formatted spacing fields
741 54686973207369676e617475726520636f6e7461696e73206e6f20666f726d61747465642073706163696e67206669656c6473
743 Formatted line encoding should be used if there are user added spacing entries [{}, (), *]
744 included on the line. Prefix formatted lines with '=:' (no quote marks).
748 =:This signature{-10}contains several(25|26|27)formatted spacing*fields
752 54686973207369676e6174757265{-10}636f6e7461696e73207365766572616c(25|26|27)666f726d61747465642073706163696e67*6669656c6473
754 Use 'full' encoding if you want to encode everything on the line [including {}, (), *] and 'formatted'
755 encoding if you want to encode everything on the line except the formatted character spacing fields.
757 The prefixes ('-:' and '=:') will be stripped from the line before hexadecimal encoding is done.
758 If no prefix is found at the beginning of the line, full line encoding will be done (default).
760 - It is assumed that the signatures will be created for email scanning purposes, thus the '4'
761 target type is used and full file scanning is enabled (see ClamAV signatures.pdf for details).
763 - Line numbering will be done automatically by the script.
764 " | command sed 's/^ //g'
765 echo -n "Do you wish to continue? "
766 if xshok_prompt_confirm ; then
768 echo -n "Enter the source file as /path/filename: "
770 if [ -r "$source" ] ; then
771 source_file=$(basename "$source")
773 echo "What signature prefix would you like to use? For example: 'Phish.Domains'"
774 echo "will create signatures that looks like: 'Phish.Domains.1:4:*:HexSigHere'"
776 echo -n "Enter signature prefix: "
778 path_file=$(echo "$source" | cut -d "." -f-1 | command sed 's/$/.ndb/')
779 db_file=$(basename "$path_file")
781 total=$(wc -l "$source" | cut -d " " -f1)
784 while read -r line ; do
785 line_prefix=$(echo "$line" | awk -F ':' '{print $1}')
786 if [ "$line_prefix" = "-" ] ; then
787 echo "$line" | cut -d ":" -f2- | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg' | command sed "s/^/$prefix\.$line_num:4:\*:/" >> "$path_file"
788 elif [ "$line_prefix" = "=" ] ; then
789 echo "$line" | cut -d ":" -f2- | perl -pe 's/(\{[^}]*\}|\([^)]*\)|\*)|(.)/defined $1 ? $1 : sprintf("%02lx", ord $2)/eg' | command sed "s/^/$prefix\.$line_num:4:\*:/" >> "$path_file"
791 echo "$line" | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg' | command sed "s/^/$prefix\.$line_num:4:\*:/" >> "$path_file"
793 echo "Hexadecimal encoding $source_file line: $line_num of $total"
794 line_num=$((line_num + 1))
797 echo "Source file not found, exiting..."
802 echo "Signature database file created at: $path_file"
803 if $clamscan_bin --quiet -d "$path_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
805 echo "Clamscan reports database integrity tested good."
807 echo -n "Would you like to move '$db_file' into '$clam_dbs' and reload databases?"
808 if xshok_prompt_confirm ; then
809 if ! cmp -s "$path_file" "$clam_dbs/$db_file" ; then
810 if $rsync_bin -pcqt "$path_file" "$clam_dbs" ; then
811 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
812 perms chmod -f 0644 "$clam_dbs"/"$db_file"
813 if [ "$selinux_fixes" == "yes" ] ; then
814 restorecon "$clam_dbs/$db_file"
818 echo "Signature database '$db_file' was successfully implemented and ClamD databases reloaded."
821 echo "Failed to add/update '$db_file', ClamD database not reloaded."
825 echo "Database '$db_file' has not changed - skipping"
829 echo "No action taken."
833 echo "Clamscan reports that '$db_file' signature database integrity tested bad."
838 #Remove the clamav-unofficial-sigs script
839 function remove_script () {
841 if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
842 echo "This script (clamav-unofficial-sigs) was installed on the system via '$pkg_mgr'"
843 echo "use '$pkg_rm' to remove the script and all of its associated files and databases from the system."
846 cron_file_full_path="$cron_dir/$cron_filename"
847 logrotate_file_full_path="$logrotate_dir/$logrotate_filename"
848 man_file_full_path="$man_dir/$man_filename"
850 echo "This will remove the workdir ($work_dir), logrotate file ($logrotate_file_full_path), cron file ($cron_file_full_path), man file ($man_file_full_path)"
851 echo "Are you sure you want to remove the clamav-unofficial-sigs script and all of its associated files, third-party databases, and work directory from the system?"
852 if xshok_prompt_confirm ; then
853 echo "This can not be undone are you sure ?"
854 if xshok_prompt_confirm ; then
855 if [ -r "$work_dir_work_configs/purge.txt" ] ; then
857 while read -r file ; do
858 xshok_is_file "$file" && rm -f -- "$file"
859 echo " Removed file: $file"
860 done < "$work_dir_work_configs"/purge.txt
861 if [ -r "$cron_file_full_path" ] ; then
862 xshok_is_file "$cron_file_full_path" && rm -f "$cron_file_full_path"
863 echo " Removed file: $cron_file_full_path"
865 if [ -r "$logrotate_file_full_path" ] ; then
866 xshok_is_file "$logrotate_file_full_path" && rm -f "$logrotate_file_full_path"
867 echo " Removed file: $logrotate_file_full_path"
869 if [ -r "$man_file_full_path" ] ; then
870 xshok_is_file "$man_file_full_path" && rm -f "$man_file_full_path"
871 echo " Removed file: $man_file_full_path"
874 #rather keep the configs
875 #rm -f -- "$default_config" && echo " Removed file: $default_config"
876 #rm -f -- "$0" && echo " Removed file: $0"
877 xshok_is_subdir "$work_dir" && rm -rf -- "$work_dir" && echo " Removed script working directories: $work_dir"
879 echo " The clamav-unofficial-sigs script and all of its associated files, third-party"
880 echo " databases, and work directories have been successfully removed from the system."
883 echo " Cannot locate 'purge.txt' file in $work_dir_work_configs."
884 echo " Files and signature database will need to be removed manually."
895 #Clamscan integrity test a specific database file
896 function clamscan_integrity_test_specific_database_file () { #databasefile
899 input=$(echo "$1" | awk -F '/' '{print $NF}')
900 db_file=$(find "$work_dir" -name "$input")
901 if [ -r "$db_file" ] ; then
902 echo "Clamscan integrity testing: $db_file"
904 $clamscan_bin --quiet -d "$db_file" "$work_dir_work_configs/scan-test.txt"
905 if [ "$?" -eq "0" ]; then
906 echo "Clamscan reports that '$input' database integrity tested GOOD"
909 echo "Clamscan reports that '$input' database integrity tested BAD"
913 echo "File '$input' cannot be found."
914 echo "Here is a list of third-party databases that can be clamscan integrity tested:"
916 echo "=== Sanesecurity ==="
917 ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_sanesecurity"
919 echo "=== SecuriteInfo ==="
920 ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_securiteinfo"
922 echo "=== MalwarePatrol ==="
923 ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_malwarepatrol"
925 echo "=== Linux Malware Detect ==="
926 ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_linuxmalwaredetect"
928 echo "=== Linux Malware Detect ==="
929 ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_yararulesproject"
931 echo "=== User Defined Databases ==="
932 ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_add"
934 echo "Check the file name and try again..."
937 xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
942 #output names of any third-party signatures that triggered during the HAM directory scan
943 function output_signatures_triggered_during_ham_directory_scan () {
945 if [ -n "$ham_dir" ] ; then
946 if [ -r "$work_dir_work_configs/whitelist.hex" ] ; then
947 echo "The following third-party signatures triggered hits during the HAM Directory scan:"
949 $grep_bin -h -f "$work_dir_work_configs/whitelist.hex" "$work_dir"/*/*.ndb | cut -d ":" -f1
951 echo "No third-party signatures have triggered hits during the HAM Directory scan."
954 echo "Ham directory scanning is not currently enabled in the script's configuration file."
958 #Adds a signature whitelist entry in the newer ClamAV IGN2 format
959 function add_signature_whitelist_entry () {
961 echo "Input a third-party signature name that you wish to whitelist due to false-positives"
962 echo "and press enter (do not include '.UNOFFICIAL' in the signature name nor add quote"
963 echo "marks to the input string):"
966 if [ -n "$input" ] ; then
967 cd "$clam_dbs" || exit
968 input=$(echo "$input" | tr -d "'" | tr -d '"')
969 sig_full=$($grep_bin -H "$input" ./*.*db)
970 sig_name=$(echo "$sig_full" | cut -d ":" -f2)
971 if [ -n "$sig_name" ] ; then
972 if ! $grep_bin "$sig_name" my-whitelist.ign2 > /dev/null 2>&1 ; then
973 cp -f my-whitelist.ign2 "$work_dir_work_configs" 2>/dev/null
974 echo "$sig_name" >> "$work_dir_work_configs/my-whitelist.ign2"
975 echo "$sig_full" >> "$work_dir_work_configs/tracker.txt"
976 if $clamscan_bin --quiet -d "$work_dir_work_configs/my-whitelist.ign2" "$work_dir_work_configs/scan-test.txt" ; then
977 if $rsync_bin -pcqt "$work_dir_work_configs/my-whitelist.ign2" "$clam_dbs" ; then
978 perms chown -f "$clam_user:$clam_group" my-whitelist.ign2
980 if [ ! -s "$work_dir_work_configs/monitor-ign.txt" ] ; then
981 # Create "monitor-ign.txt" file for clamscan database integrity testing.
982 echo "This is the monitor ignore file..." > "$work_dir_work_configs/monitor-ign.txt"
985 perms chmod -f 0644 my-whitelist.ign2 "$work_dir_work_configs/monitor-ign.txt"
986 if [ "$selinux_fixes" == "yes" ] ; then
987 restorecon "$clam_dbs/local.ign"
991 echo "Signature '$input' has been added to my-whitelist.ign2 and"
992 echo "all databases have been reloaded. The script will track any changes"
993 echo "to the offending signature and will automatically remove it if the"
994 echo "signature is modified or removed from the third-party database."
997 echo "Failed to successfully update my-whitelist.ign2 file - SKIPPING."
1001 echo "Clamscan reports my-whitelist.ign2 database integrity is bad - SKIPPING."
1005 echo "Signature '$input' already exists in my-whitelist.ign2 - no action taken."
1009 echo "Signature '$input' could not be found."
1011 echo "This script will only create a whitelise entry in my-whitelist.ign2 for ClamAV"
1012 echo "'UNOFFICIAL' third-Party signatures as found in the *.ndb *.hdb *.db databases."
1015 echo "No input detected - no action taken."
1019 #Clamscan reload database
1020 function clamscan_reload_dbs () {
1021 # Reload all clamd databases if updates detected and $reload_dbs" is set to "yes"
1022 if [ "$reload_dbs" = "yes" ] ; then
1023 if [ "$do_clamd_reload" != "0" ] ; then
1024 if [ "$do_clamd_reload" = "1" ] ; then
1025 xshok_pretty_echo_and_log "Update(s) detected, reloading ClamAV databases" "="
1026 elif [ "$do_clamd_reload" = "2" ] ; then
1027 xshok_pretty_echo_and_log "Database removal(s) detected, reloading ClamAV databases" "="
1028 elif [ "$do_clamd_reload" = "3" ] ; then
1029 xshok_pretty_echo_and_log "File 'local.ign' has changed, reloading ClamAV databases" "="
1030 elif [ "$do_clamd_reload" = "4" ] ; then
1031 xshok_pretty_echo_and_log "File 'my-whitelist.ign2' has changed, reloading ClamAV databases" "="
1033 xshok_pretty_echo_and_log "Update(s) detected, reloading ClamAV databases" "="
1036 if [[ $($clamd_reload_opt 2>&1) = *"ERROR"* ]] ; then
1037 xshok_pretty_echo_and_log "ERROR: Failed to reload, trying again" "-"
1038 if [ -r "$clamd_pid" ] ; then
1039 mypid=$(cat "$clamd_pid")
1041 if [ $? -eq 0 ] ; then
1042 xshok_pretty_echo_and_log "ClamAV databases Reloaded" "="
1044 xshok_pretty_echo_and_log "ERROR: Failed to reload, forcing clamd to restart" "-"
1045 if [ -z "$clamd_restart_opt" ] ; then
1046 xshok_pretty_echo_and_log "WARNING: Check the script's configuration file, 'reload_dbs' enabled but no 'clamd_restart_opt'" "*"
1049 xshok_pretty_echo_and_log "ClamAV Restarted" "="
1053 xshok_pretty_echo_and_log "ERROR: Failed to reload, forcing clamd to restart" "="
1054 if [ -z "$clamd_restart_opt" ] ; then
1055 xshok_pretty_echo_and_log "WARNING: Check the script's configuration file, 'reload_dbs' enabled but no 'clamd_restart_opt'" "*"
1058 xshok_pretty_echo_and_log "ClamAV Restarted" "="
1062 xshok_pretty_echo_and_log "ClamAV databases Reloaded" "="
1065 xshok_pretty_echo_and_log "No updates detected, ClamAV databases were not reloaded" "="
1068 xshok_pretty_echo_and_log "Database reload has been disabled in the configuration file" "="
1073 # If ClamD status check is enabled ("clamd_socket" variable is uncommented
1074 # and the socket path is correctly specified in "User Edit" section above),
1075 # then test to see if clamd is running or not.
1076 function check_clamav () {
1077 if [ -n "$clamd_socket" ] ; then
1078 if [ -S "$clamd_socket" ] ; then
1079 if [ "$(perl -e 'use IO::Socket::UNIX; print $IO::Socket::UNIX::VERSION,"\n"' 2>/dev/null)" ] ; then
1081 if [ "$(perl -MIO::Socket::UNIX -we '$s = IO::Socket::UNIX->new(shift); $s->print("PING"); print $s->getline; $s->close' "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
1083 xshok_pretty_echo_and_log "ClamD is running" "="
1086 socat="$(which socat 2>/dev/null)"
1087 if [ -n "$socat" ] && [ -x "$socat" ] ; then
1089 if [ "$( (echo "PING"; sleep 1;) | socat - "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
1091 xshok_pretty_echo_and_log "ClamD is running" "="
1095 if [ -z "$io_socket1" ] && [ -z "$socket_cat1" ] ; then
1096 xshok_pretty_echo_and_log "WARNING: socat or perl module 'IO::Socket::UNIX' not found, cannot test if ClamD is running" "*"
1098 if [ -z "$io_socket2" ] && [ -z "$socket_cat2" ] ; then
1100 xshok_pretty_echo_and_log "ALERT: CLAMD IS NOT RUNNING!" "="
1101 if [ -n "$clamd_restart_opt" ] ; then
1102 xshok_pretty_echo_and_log "Attempting to start ClamD..." "-"
1103 if [ -n "$io_socket1" ] ; then
1104 $clamd_restart_opt > /dev/null && sleep 5
1105 if [ "$(perl -MIO::Socket::UNIX -we '$s = IO::Socket::UNIX->new(shift); $s->print("PING"); print $s->getline; $s->close' "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
1106 xshok_pretty_echo_and_log "ClamD was successfully started" "="
1108 xshok_pretty_echo_and_log "ERROR: CLAMD FAILED TO START" "="
1112 if [ -n "$socket_cat1" ] ; then
1113 $clamd_restart_opt > /dev/null && sleep 5
1114 if [ "$( (echo "PING"; sleep 1;) | socat - "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
1115 xshok_pretty_echo_and_log "ClamD was successfully started" "="
1117 xshok_pretty_echo_and_log "ERROR: CLAMD FAILED TO START" "="
1126 xshok_pretty_echo_and_log "WARNING: $clamd_socket is not a usable socket" "*"
1129 xshok_pretty_echo_and_log "WARNING: clamd_socket is not defined in the configuration file" "*"
1133 #function to check for a new version
1134 function check_new_version () {
1135 if [ "$wget_bin" != "" ] ; then
1136 latest_version="$($wget_bin https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/clamav-unofficial-sigs.sh -O - 2> /dev/null | $grep_bin "script""_version=" | cut -d\" -f2)"
1138 latest_version="$($curl_bin https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/clamav-unofficial-sigs.sh 2> /dev/null | $grep_bin "script""_version=" | cut -d\" -f2)"
1140 if [ "$latest_version" ] ; then
1141 if [ ! "$latest_version" == "$script_version" ] ; then
1142 xshok_pretty_echo_and_log "New version : v$latest_version @ https://github.com/extremeshok/clamav-unofficial-sigs" "-"
1147 #function for help and usage
1149 # help_and_usage "1" - enables the man output formatting
1150 # help_and_usage - normal help output formatting
1151 function help_and_usage () {
1154 #option_format_start
1158 #option_format_blankline
1160 #option_format_tab_line
1163 #option_format_start
1167 #option_format_blankline
1169 #option_format_tab_line
1173 helpcontents=$(cat << EOF
1174 $ofs Usage: $(basename "$0") $ofe [OPTION] [PATH|FILE]
1176 $ofs -c, --config $ofe Use a specific configuration file or directory $oft eg: '-c /your/dir' or ' -c /your/file.name' $oft Note: If a directory is specified the directory must contain atleast: $oft master.conf, os.conf or user.conf $oft Default Directory: $config_dir
1178 $ofs -F, --force $ofe Force all databases to be downloaded, could cause ip to be blocked
1180 $ofs -h, --help $ofe Display this script's help and usage information
1182 $ofs -V, --version $ofe Output script version and date information
1184 $ofs -v, --verbose $ofe Be verbose, enabled when not run under cron
1186 $ofs -s, --silence $ofe Only output error messages, enabled when run under cron
1188 $ofs -d, --decode-sig $ofe Decode a third-party signature either by signature name $oft (eg: Sanesecurity.Junk.15248) or hexadecimal string. $oft This flag will 'NOT' decode image signatures
1190 $ofs -e, --encode-string $ofe Hexadecimal encode an entire input string that can $oft be used in any '*.ndb' signature database file
1192 $ofs -f, --encode-formatted $ofe Hexadecimal encode a formatted input string containing $oft signature spacing fields '{}, (), *', without encoding $oft the spacing fields, so that the encoded signature $oft can be used in any '*.ndb' signature database file
1194 $ofs -g, --gpg-verify $ofe GPG verify a specific Sanesecurity database file $oft eg: '-g filename.ext' (do not include file path)
1196 $ofs -i, --information $ofe Output system and configuration information for $oft viewing or possible debugging purposes
1198 $ofs -m, --make-database $ofe Make a signature database from an ascii file containing $oft data strings, with one data string per line. Additional $oft information is provided when using this flag
1200 $ofs -t, --test-database $ofe Clamscan integrity test a specific database file $oft eg: '-t filename.ext' (do not include file path)
1202 $ofs -o, --output-triggered $ofe If HAM directory scanning is enabled in the script's $oft configuration file, then output names of any third-party $oft signatures that triggered during the HAM directory scan
1204 $ofs -w, --whitelist $ofe Adds a signature whitelist entry in the newer ClamAV IGN2 $oft format to 'my-whitelist.ign2' in order to temporarily resolve $oft a false-positive issue with a specific third-party signature. $oft Script added whitelist entries will automatically be removed $oft if the original signature is either modified or removed from $oft the third-party signature database
1206 $ofs --check-clamav $ofe If ClamD status check is enabled and the socket path is correctly $oft specifiedthen test to see if clamd is running or not
1208 $ofs --install-all $ofe Install and generate the cron, logroate and man files, autodetects the values $oft based on your config files
1210 $ofs --install-cron $ofe Install and generate the cron file, autodetects the values $oft based on your config files
1212 $ofs --install-logrotate $ofe Install and generate the logrotate file, autodetects the $oft values based on your config files
1214 $ofs --install-man $ofe Install and generate the man file, autodetects the $oft values based on your config files
1216 $ofs --remove-script $ofe Remove the clamav-unofficial-sigs script and all of $oft its associated files and databases from the system
1219 ) #this is very important...
1222 echo "${helpcontents//-/\\-}"
1224 echo -e "$helpcontents"
1228 ################################################################################
1230 ################################################################################
1233 script_version="5.4.1"
1234 script_version_date="20 July 2016"
1235 minimum_required_config_version="65"
1236 minimum_yara_clamav_version="0.99"
1238 #default config files
1239 config_dir="/etc/clamav-unofficial-sigs"
1240 config_files=("$config_dir/master.conf" "$config_dir/os.conf" "$config_dir/user.conf")
1245 comment_silence="no"
1246 logging_enabled="no"
1250 we_have_a_config="0"
1252 ## Solaris which function returns garbage when the program is not found
1253 ## only define the new which function if running under Solaris
1254 if [ "$(uname -s)" = "SunOS" ] ; then
1256 # use the switch -p to ignore ksh internal commands
1261 #Default Binaries & Commands
1262 clamd_reload_opt="clamdscan --reload"
1263 uname_bin=$(which uname)
1264 clamscan_bin=$(which clamscan)
1265 rsync_bin=$(which rsync)
1266 #detect support for wget
1267 if [ -x /usr/sfw/bin/wget ] ; then
1268 wget_bin="/usr/sfw/bin/wget"
1270 wget_bin=$(which wget)
1272 if [ "$wget_bin" == "" ] ; then
1273 curl_bin=$(which curl)
1275 #detect supprot for gnu grep
1276 if [ -x /usr/gnu/bin/grep ] ; then
1277 grep_bin="/usr/gnu/bin/grep"
1279 grep_bin=$(which grep)
1281 if [ -x /opt/csw/bin/gpg ] ; then
1282 gpg_bin="/opt/csw/bin/gpg"
1284 gpg_bin=$(which gpg)
1286 if [ "$gpg_bin" == "" ] ; then
1287 gpg_bin=$(which gpg2)
1293 ##Usage: echo "${BOLD}-a${NORM}"
1309 # Generic command line options
1312 -c | --config ) xshok_check_s2 "$2"; custom_config="$2"; shift 2; break ;;
1313 -F | --force ) force_updates="yes"; shift 1; break ;;
1314 -v | --verbose ) force_verbose="yes"; shift 1; break ;;
1315 -s | --silence ) force_verbose="no"; shift 1; break ;;
1321 if [ "$force_verbose" == "yes" ] ; then
1323 downloader_silence="no"
1326 comment_silence="no"
1329 downloader_silence="yes"
1332 comment_silence="yes"
1335 xshok_pretty_echo_and_log "" "#" "80"
1336 xshok_pretty_echo_and_log " eXtremeSHOK.com ClamAV Unofficial Signature Updater"
1337 xshok_pretty_echo_and_log " Version: v$script_version ($script_version_date)"
1338 xshok_pretty_echo_and_log " Required Configuration Version: v$minimum_required_config_version"
1339 xshok_pretty_echo_and_log " Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com"
1340 xshok_pretty_echo_and_log "" "#" "80"
1342 # Generic command line options
1345 -h | --help ) help_and_usage; exit; break ;;
1346 -V | --version ) exit; break ;;
1351 ## CONFIG LOADING AND ERROR CHECKING ##############################################
1352 if [ "$custom_config" != "no" ] ; then
1353 if [ -d "$custom_config" ] ; then
1354 # Assign the custom config dir and remove trailing / (removes / and //)
1355 config_dir=$(echo "$custom_config" | sed 's:/*$::')
1356 config_files=("$config_dir/master.conf" "$config_dir/os.conf" "$config_dir/user.conf")
1358 config_files=("$custom_config")
1362 for config_file in "${config_files[@]}" ; do
1363 if [ -r "$config_file" ] ; then #exists and readable
1364 we_have_a_config="1"
1366 xshok_pretty_echo_and_log "Loading config: $config_file" "="
1370 if [ "$(uname -s)" = "SunOS" ] ; then
1371 #Solaris FIXES only, i had issues with running with a single command..
1372 clean_config=$(command sed -e '/^#.*/d' "$config_file") # comment line
1373 clean_config=$(echo "$clean_config" | sed -e 's/#[[:space:]].*//') # comment line (duplicated)
1374 clean_config=$(echo "$clean_config" | sed -e '/^[[:blank:]]*#/d;s/#.*//') #comments at end of line
1375 clean_config=$(echo "$clean_config" | sed -e 's/^[ \t]*//;s/[ \t]*$//') #trailing and leading whitespace
1376 clean_config=$(echo "$clean_config" | sed -e '/^\s*$/d') #blank lines
1378 # delete lines beginning with #
1379 # delete from ' #' to end of the line
1380 # delete from '# ' to end of the line
1381 # delete both trailing and leading whitespace
1382 # delete all trailing whitespace
1383 # delete all empty lines
1384 clean_config=$(command sed -e '/^#.*/d' -e 's/[[:space:]]#.*//' -e 's/#[[:space:]].*//' -e 's/^[ \t]*//;s/[ \t]*$//' -e '/^\s*$/d' "$config_file")
1387 ### config error checking
1388 # check "" are an even number
1389 config_check="${clean_config//[^\"]}"
1390 if [ $(( ${#config_check} % 2)) -eq 1 ] ; then
1391 xshok_pretty_echo_and_log "ERROR: Your configuration has errors, every \" requires a closing \"" "="
1395 # check there is an = for every set of "" #optional whitespace \s* between = and "
1396 config_check_vars=$(echo "$clean_config" | $grep_bin -c '=\s*\"' )
1398 if [ $(( ${#config_check} / 2)) -ne "$config_check_vars" ] ; then
1399 xshok_pretty_echo_and_log "ERROR: Your configuration has errors, every = requires a pair of \"\"" "="
1404 for i in "${clean_config[@]}" ; do
1405 eval "$(echo "${i}" | command sed -e 's/[[:space:]]*$//' 2> /dev/null)"
1412 # Assign the log_file_path earlier and remove trailing / (removes / and //)
1413 log_file_path=$(echo "$log_file_path" | sed 's:/*$::')
1414 #Only start logging once all the configs have been loaded
1415 if [ "$logging_enabled" == "yes" ] ; then
1419 ## Make sure we have a readable config file
1420 if [ "$we_have_a_config" == "0" ] ; then
1421 xshok_pretty_echo_and_log "ERROR: Config file/s could NOT be read/loaded" "="
1425 #prevent some issues with an incomplete or only a user.conf being loaded
1426 if [ $config_version == "0" ] ; then
1427 xshok_pretty_echo_and_log "ERROR: Config file/s are missing important contents" "="
1428 xshok_pretty_echo_and_log "Note: Possible fix would be to point the script to the dir with the configs"
1432 #config version validation
1433 if [ $config_version -lt $minimum_required_config_version ] ; then
1434 xshok_pretty_echo_and_log "ERROR: Your config version $config_version is not compatible with the min required version $minimum_required_config_version" "="
1438 # Check to see if the script's "USER CONFIGURATION FILE" has been completed.
1439 if [ "$user_configuration_complete" != "yes" ] ; then
1440 xshok_pretty_echo_and_log "WARNING: SCRIPT CONFIGURATION HAS NOT BEEN COMPLETED" "*"
1441 xshok_pretty_echo_and_log "Please review the script configuration files."
1445 # Assign the directories and remove trailing / (removes / and //)
1446 work_dir=$(echo "$work_dir" | sed 's:/*$::')
1448 #Allow overriding of all the individual workdirs, this is mainly to aid package maintainers
1449 if [ ! -n "$work_dir_sanesecurity" ] ; then
1450 work_dir_sanesecurity=$(echo "$work_dir/$sanesecurity_dir" | sed 's:/*$::')
1452 work_dir_sanesecurity=$(echo "$work_dir_sanesecurity" | sed 's:/*$::')
1454 if [ ! -n "$work_dir_securiteinfo" ] ; then
1455 work_dir_securiteinfo=$(echo "$work_dir/$securiteinfo_dir" | sed 's:/*$::')
1457 work_dir_securiteinfo=$(echo "$work_dir_securiteinfo" | sed 's:/*$::')
1459 if [ ! -n "$work_dir_linuxmalwaredetect" ] ; then
1460 work_dir_linuxmalwaredetect=$(echo "$work_dir/$linuxmalwaredetect_dir" | sed 's:/*$::')
1462 work_dir_linuxmalwaredetect=$(echo "$work_dir_linuxmalwaredetect" | sed 's:/*$::')
1464 if [ ! -n "$work_dir_malwarepatrol" ] ; then
1465 work_dir_malwarepatrol=$(echo "$work_dir/$malwarepatrol_dir" | sed 's:/*$::')
1467 work_dir_malwarepatrol=$(echo "$work_dir_malwarepatrol" | sed 's:/*$::')
1469 if [ ! -n "$work_dir_yararulesproject" ] ; then
1470 work_dir_yararulesproject=$(echo "$work_dir/$yararulesproject_dir" | sed 's:/*$::')
1472 work_dir_yararulesproject=$(echo "$work_dir_yararulesproject" | sed 's:/*$::')
1474 if [ ! -n "$work_dir_add" ] ; then
1475 work_dir_add=$(echo "$work_dir/$add_dir" | sed 's:/*$::')
1477 work_dir_add=$(echo "$work_dir_add" | sed 's:/*$::')
1479 if [ ! -n "$work_dir_work_configs" ] ; then
1480 work_dir_work_configs=$(echo "$work_dir/$work_dir_configs" | sed 's:/*$::')
1482 work_dir_work_configs=$(echo "$work_dir_work_configs" | sed 's:/*$::')
1484 if [ ! -n "$work_dir_gpg" ] ; then
1485 work_dir_gpg=$(echo "$work_dir/$gpg_dir" | sed 's:/*$::')
1487 work_dir_gpg=$(echo "$work_dir_gpg" | sed 's:/*$::')
1490 if [ ! -n "$work_dir_pid" ] ; then
1491 work_dir_pid=$(echo "$work_dir/$pid_dir" | sed 's:/*$::')
1493 work_dir_pid=$(echo "$work_dir_pid" | sed 's:/*$::')
1496 # Assign defaults if not defined
1497 if [ ! -n "$cron_dir" ] ; then
1498 cron_dir="/etc/cron.d"
1500 cron_dir=$(echo "$cron_dir" | sed 's:/*$::')
1501 if [ ! -n "$cron_filename" ] ; then
1502 cron_filename="clamav-unofficial-sigs"
1504 if [ ! -n "$logrotate_dir" ] ; then
1505 logrotate_dir="/etc/logrotate.d"
1507 logrotate_dir=$(echo "$logrotate_dir" | sed 's:/*$::')
1508 if [ ! -n "$logrotate_filename" ] ; then
1509 logrotate_filename="clamav-unofficial-sigs"
1511 if [ ! -n "$man_dir" ] ; then
1512 man_dir="/usr/share/man/man8"
1514 man_dir=$(echo "$man_dir" | sed 's:/*$::')
1515 if [ ! -n "$man_filename" ] ; then
1516 man_filename="clamav-unofficial-sigs.8"
1518 if [ ! -n "$man_log_file_full_path" ] ; then
1519 man_log_file_full_path="$log_file_path/$log_file_name"
1523 #Check default Binaries & Commands are defined
1524 if [ "$clamd_reload_opt" == "" ] ; then
1525 xshok_pretty_echo_and_log "ERROR: Missing clamd_reload_opt" "="
1528 if [ "$uname_bin" == "" ] ; then
1529 xshok_pretty_echo_and_log "ERROR: uname (uname_bin) not found" "="
1532 if [ "$clamscan_bin" == "" ] ; then
1533 xshok_pretty_echo_and_log "ERROR: clamscan binary (clamscan_bin) not found" "="
1536 if [ "$rsync_bin" == "" ] ; then
1537 xshok_pretty_echo_and_log "ERROR: rsync binary (rsync_bin) not found" "="
1540 if [ "$wget_bin" == "" ] ; then
1541 if [ "$curl_bin" == "" ] ; then
1542 xshok_pretty_echo_and_log "ERROR: wget and curl binaries not found, script requires either wget or curl" "="
1546 if [ "$gpg_bin" == "" ] ; then
1547 xshok_pretty_echo_and_log "ERROR: gpg binary (gpg_bin) not found" "="
1550 #Check default directories are defined
1551 if [ "$work_dir" == "" ] ; then
1552 xshok_pretty_echo_and_log "ERROR: working directory (work_dir) not defined" "="
1556 # Reset the update timers to force a full update.
1557 if [ "$force_updates" == "yes" ] ; then
1558 xshok_pretty_echo_and_log "Force Updates: enabled"
1559 sanesecurity_update_hours="0"
1560 securiteinfo_update_hours="0"
1561 linuxmalwaredetect_update_hours="0"
1562 malwarepatrol_update_hours="0"
1563 yararulesproject_update_hours="0"
1564 additional_update_hours="0"
1567 # Enable pid file to prevent issues with multiple instances
1568 # opted not to use flock as it appears to have issues with some systems
1569 if [ "$enable_locking" == "yes" ] ; then
1570 xshok_mkdir_ownership "$work_dir_pid"
1571 pid_file_fullpath="$work_dir_pid/clamav-unofficial-sigs.pid"
1572 if [ -f "$pid_file_fullpath" ] ; then
1573 pid_file_pid=$(cat "$pid_file_fullpath")
1574 ps -p "$pid_file_pid" > /dev/null 2>&1
1575 if [ $? -eq 0 ] ; then
1576 xshok_pretty_echo_and_log "ERROR: Only one instance can run at the same time." "="
1579 xshok_create_pid_file "$pid_file_fullpath"
1582 xshok_create_pid_file "$pid_file_fullpath"
1584 # run this wehen the script exits
1585 trap -- "rm -f $pid_file_fullpath" EXIT
1588 # Verify the clam_user and clam_group actually exists on the system
1589 if ! xshok_user_group_exists "$clam_user" "$clam_group" ; then
1590 xshok_pretty_echo_and_log "ERROR: Either the user: $clam_user and/or group: $clam_group does not exist on the system." "="
1594 # Silence rsync output and only report errors - useful if script is run via cron.
1595 if [ "$rsync_silence" = "yes" ] ; then
1596 rsync_output_level="--quiet"
1598 rsync_output_level="--progress"
1601 # If the local rsync client supports the '--no-motd' flag, then enable it.
1602 if $rsync_bin --help | $grep_bin 'no-motd' > /dev/null ; then
1606 # If the local rsync client supports the '--contimeout' flag, then enable it.
1607 if $rsync_bin --help | $grep_bin 'contimeout' > /dev/null ; then
1608 connect_timeout="--contimeout=$rsync_connect_timeout"
1611 # Silence wget output and only report errors - useful if script is run via cron.
1612 if [ "$downloader_silence" = "yes" ] ; then
1613 wget_output_level="--quiet" #--quiet
1614 curl_output_level="--silent --show-error"
1616 wget_output_level="--no-verbose"
1617 curl_output_level=""
1620 #suppress ssl warnings
1621 if [ "$downloader_ignore_ssl" = "yes" ] ; then
1622 wget_insecure="--no-check-certificate"
1623 curl_insecure="--insecure"
1629 # This scripts name and path
1630 this_script_name="$(basename "$0")"
1631 this_script_path="$( cd "$(dirname "$0")" ; pwd -P )"
1632 this_script_full_path="$this_script_path/$this_script_name"
1634 #set the script to 755 permissions
1635 if xshok_is_root ; then
1636 if [ "$setmode" == "yes" ] ; then
1637 if [ ! -x "$this_script_path/$this_script_name" ] ; then
1638 chmod 755 "$this_script_path/$this_script_name"
1639 xshok_pretty_echo_and_log "Fixing permission on $this_script_path/$this_script_name" "="
1647 ################################################################################
1649 ################################################################################
1653 -d | --decode-sig ) decode_third_party_signature_by_signature_name; exit; break ;;
1654 -e | --encode-string ) hexadecimal_encode_entire_input_string; exit; break ;;
1655 -f | --encode-formatted ) hexadecimal_encode_formatted_input_string; exit; break ;;
1656 -g | --gpg-verify ) xshok_check_s2 "$2"; gpg_verify_specific_sanesecurity_database_file "$2"; exit; break ;;
1657 -i | --information ) output_system_configuration_information; exit; break ;;
1658 -m | --make-database ) make_signature_database_from_ascii_file; exit; break ;;
1659 -t | --test-database ) xshok_check_s2 "$2"; clamscan_integrity_test_specific_database_file "$2"; exit; break ;;
1660 -o | --output-triggered ) output_signatures_triggered_during_ham_directory_scan; exit; break ;;
1661 -w | --whitelist ) add_signature_whitelist_entry; exit; break ;;
1662 --check-clamav ) check_clamav; exit; break ;;
1663 --install-all ) install_cron; install_logrotate; install_man; exit; break ;;
1664 --install-cron ) install_cron; exit; break ;;
1665 --install-logrotate ) install_logrotate; exit; break ;;
1666 --install-man ) install_man; exit; break ;;
1667 --remove-script ) remove_script; exit; break ;;
1672 xshok_pretty_echo_and_log "Preparing Databases" "="
1674 # Check yararule support is available
1675 if [ "$enable_yararules" == "yes" ] ; then
1676 current_clamav_version=$($clamscan_bin -V | cut -d " " -f2 | cut -d "/" -f1 | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')
1677 minimum_yara_clamav_version=$(echo "$minimum_yara_clamav_version" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')
1678 #Check current clamav version against the minimum required version for yara support
1679 if [ "$current_clamav_version" -lt "$minimum_yara_clamav_version" ] ; then #older
1680 yararulesproject_enabled="no"
1681 enable_yararules="no"
1682 xshok_pretty_echo_and_log "Notice: Yararules Disabled due to clamav being older than the minimum required version"
1685 yararulesproject_enabled="no"
1686 enable_yararules="no"
1689 # Generate the signature databases
1690 if [ "$sanesecurity_enabled" == "yes" ] ; then
1691 if [ -n "$sanesecurity_dbs" ] ; then
1692 if [ -n "$sanesecurity_dbs_rating" ] ; then
1693 sanesecurity_dbs="$(xshok_database "$sanesecurity_dbs" "$sanesecurity_dbs_rating")"
1695 sanesecurity_dbs="$(xshok_database "$sanesecurity_dbs" "$default_dbs_rating")"
1699 if [ "$securiteinfo_enabled" == "yes" ] ; then
1700 if [ -n "$securiteinfo_dbs" ] ; then
1701 if [ -n "$securiteinfo_dbs_rating" ] ; then
1702 securiteinfo_dbs="$(xshok_database "$securiteinfo_dbs" "$securiteinfo_dbs_rating")"
1704 securiteinfo_dbs="$(xshok_database "$securiteinfo_dbs" "$default_dbs_rating")"
1708 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
1709 if [ -n "$linuxmalwaredetect_dbs" ] ; then
1710 if [ -n "$linuxmalwaredetect_dbs_rating" ] ; then
1711 linuxmalwaredetect_dbs="$(xshok_database "$linuxmalwaredetect_dbs" "$linuxmalwaredetect_dbs_rating")"
1713 linuxmalwaredetect_dbs="$(xshok_database "$linuxmalwaredetect_dbs" "$default_dbs_rating")"
1717 if [ "$yararulesproject_enabled" == "yes" ] ; then
1718 if [ -n "$yararulesproject_dbs" ] ; then
1719 if [ -n "$yararulesproject_dbs_rating" ] ; then
1720 yararulesproject_dbs="$(xshok_database "$yararulesproject_dbs" "$yararulesproject_dbs_rating")"
1722 yararulesproject_dbs="$(xshok_database "$yararulesproject_dbs" "$default_dbs_rating")"
1727 # Set the variables for MalwarePatrol
1728 if [ "$malwarepatrol_free" == "yes" ] ; then
1729 malwarepatrol_product_code="8"
1730 malwarepatrol_list="clamav_basic"
1732 if [ -z $malwarepatrol_list ] ; then
1733 malwarepatrol_list="clamav_basic"
1735 if [ -z $malwarepatrol_product_code ] ; then
1736 # Not sure, it may be better to return an error.
1737 malwarepatrol_product_code=8
1740 if [ $malwarepatrol_list == "clamav_basic" ] ; then
1741 malwarepatrol_db="malwarepatrol.db"
1743 malwarepatrol_db="malwarepatrol.ndb"
1745 malwarepatrol_url="$malwarepatrol_url?product=$malwarepatrol_product_code&list=$malwarepatrol_list"
1747 # If "ham_dir" variable is set, then create initial whitelist files (skipped if first-time script run).
1748 test_dir="$work_dir/test"
1749 if [ -n "$ham_dir" ] && [ -d "$work_dir" ] && [ ! -d "$test_dir" ] ; then
1750 if [ -d "$ham_dir" ] ; then
1751 xshok_mkdir_ownership "$test_dir"
1752 cp -f "$work_dir"/*/*.ndb "$test_dir"
1753 $clamscan_bin --infected --no-summary -d "$test_dir" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' >> "$work_dir_work_configs/whitelist.txt"
1754 $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir"/* | cut -d "*" -f2 | sort | uniq > "$work_dir_work_configs/whitelist.hex"
1755 cd "$test_dir" || exit
1756 for db_file in * ; do
1757 [[ -e $db_file ]] || break # handle the case of no files
1758 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$db_file" > "$db_file-tmp"
1759 mv -f "$db_file-tmp" "$db_file"
1760 if $clamscan_bin --quiet -d "$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
1761 if $rsync_bin -pcqt "$db_file" "$clam_dbs" ; then
1762 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
1763 if [ "$selinux_fixes" == "yes" ] ; then
1764 restorecon "$clam_dbs/$db_file"
1770 if [ -r "$work_dir_work_configs/whitelist.hex" ] ; then
1771 xshok_pretty_echo_and_log "Initial HAM directory scan whitelist file created in $work_dir_work_configs"
1773 xshok_pretty_echo_and_log "No false-positives detected in initial HAM directory scan"
1776 xshok_pretty_echo_and_log "WARNING: Cannot locate HAM directory: $ham_dir"
1777 xshok_pretty_echo_and_log "Skipping initial whitelist file creation. Fix 'ham_dir' path in config file"
1781 # Check to see if the working directories have been created. If not, create them. Otherwise, ignore and proceed with script.
1782 xshok_mkdir_ownership "$work_dir"
1783 xshok_mkdir_ownership "$work_dir_securiteinfo"
1784 xshok_mkdir_ownership "$work_dir_malwarepatrol"
1785 xshok_mkdir_ownership "$work_dir_linuxmalwaredetect"
1786 xshok_mkdir_ownership "$work_dir_sanesecurity"
1787 xshok_mkdir_ownership "$work_dir_yararulesproject"
1788 xshok_mkdir_ownership "$work_dir_work_configs"
1789 xshok_mkdir_ownership "$work_dir_gpg"
1790 xshok_mkdir_ownership "$work_dir_add"
1792 # Set secured access permissions to the GPG directory
1793 perms chmod -f 0700 "$work_dir_gpg"
1795 # If we haven't done so yet, download Sanesecurity public GPG key and import to custom keyring.
1796 if [ ! -s "$work_dir_gpg/publickey.gpg" ] ; then
1797 if [ "$wget_bin" != "" ] ; then
1798 #echo $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_gpg/publickey.gpg" "$sanesecurity_gpg_url"
1799 $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_gpg/publickey.gpg" "$sanesecurity_gpg_url"
1802 #echo $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_gpg/publickey.gpg" "$sanesecurity_gpg_url"
1803 $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_gpg/publickey.gpg" "$sanesecurity_gpg_url"
1806 if [ "$ret" != "0" ] ; then
1807 xshok_pretty_echo_and_log "ALERT: Could not download Sanesecurity public GPG key" "*"
1810 xshok_pretty_echo_and_log "Sanesecurity public GPG key successfully downloaded"
1811 rm -f -- "$work_dir_gpg/ss-keyring.gp*"
1812 if ! $gpg_bin -q --no-options --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg/ss-keyring.gpg" --import "$work_dir_gpg/publickey.gpg" 2>/dev/null ; then
1813 xshok_pretty_echo_and_log "ALERT: could not import Sanesecurity public GPG key to custom keyring" "*"
1816 chmod -f 0644 "$work_dir_gpg/*.*"
1817 xshok_pretty_echo_and_log "Sanesecurity public GPG key successfully imported to custom keyring"
1822 # If custom keyring is missing, try to re-import Sanesecurity public GPG key.
1823 if [ ! -s "$work_dir_gpg/ss-keyring.gpg" ] ; then
1824 rm -f -- "$work_dir_gpg/ss-keyring.gp*"
1825 if ! $gpg_bin -q --no-options --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg/ss-keyring.gpg" --import "$work_dir_gpg/publickey.gpg" 2>/dev/null ; then
1826 xshok_pretty_echo_and_log "ALERT: Custom keyring MISSING or CORRUPT! Could not import Sanesecurity public GPG key to custom keyring" "*"
1829 chmod -f 0644 "$work_dir_gpg/*.*"
1830 xshok_pretty_echo_and_log "Sanesecurity custom keyring MISSING! GPG key successfully re-imported to custom keyring"
1834 # Database update check, time randomization section. This script now
1835 # provides support for both bash and non-bash enabled system shells.
1836 if [ "$enable_random" = "yes" ] ; then
1837 if [ -n "$RANDOM" ] ; then
1838 sleep_time=$((RANDOM * $((max_sleep_time - min_sleep_time)) / 32767 + min_sleep_time))
1841 while [ "$sleep_time" -lt "$min_sleep_time" ] || [ "$sleep_time" -gt "$max_sleep_time" ] ; do
1842 sleep_time=$(head -1 /dev/urandom | cksum | awk '{print $2}')
1845 if [ ! -t 0 ] ; then
1846 xshok_pretty_echo_and_log "$(date) - Pausing database file updates for $sleep_time seconds..."
1848 xshok_pretty_echo_and_log "$(date) - Pause complete, checking for new database files..."
1852 # Create "scan-test.txt" file for clamscan database integrity testing.
1853 if [ ! -s "$work_dir_work_configs/scan-test.txt" ] ; then
1854 echo "This is the clamscan test file..." > "$work_dir_work_configs/scan-test.txt"
1857 # If rsync proxy is defined in the config file, then export it for use.
1858 if [ -n "$rsync_proxy" ] ; then
1859 RSYNC_PROXY="$rsync_proxy"
1863 # Create $current_dbsfiles containing lists of current and previously active 3rd-party databases
1864 # so that databases and/or backup files that are no longer being used can be removed.
1865 current_tmp="$work_dir_work_configs/current-dbs.tmp"
1866 current_dbs="$work_dir_work_configs/current-dbs.txt"
1868 if [ "$sanesecurity_enabled" == "yes" ] ; then
1869 # Create the Sanesecurity rsync "include" file (defines which files to download).
1870 sanesecurity_include_dbs="$work_dir_work_configs/ss-include-dbs.txt"
1871 if [ -n "$sanesecurity_dbs" ] ; then
1872 rm -f -- "$sanesecurity_include_dbs" "$work_dir_sanesecurity/*.sha256"
1873 for db in $sanesecurity_dbs ; do
1874 echo "$db" >> "$sanesecurity_include_dbs"
1875 echo "$db.sig" >> "$sanesecurity_include_dbs"
1877 echo "$work_dir_sanesecurity/$db" >> "$current_tmp"
1878 echo "$work_dir_sanesecurity/$db.sig" >> "$current_tmp"
1883 if [ "$securiteinfo_enabled" == "yes" ] ; then
1884 if [ -n "$securiteinfo_dbs" ] ; then
1885 for db in $securiteinfo_dbs ; do
1886 echo "$work_dir_securiteinfo/$db" >> "$current_tmp"
1891 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
1892 if [ -n "$linuxmalwaredetect_dbs" ] ; then
1893 for db in $linuxmalwaredetect_dbs ; do
1894 echo "$work_dir_linuxmalwaredetect/$db" >> "$current_tmp"
1899 if [ "$malwarepatrol_enabled" == "yes" ] ; then
1900 if [ -n "$malwarepatrol_db" ] ; then
1901 echo "$work_dir_malwarepatrol/$malwarepatrol_db" >> "$current_tmp"
1905 if [ "$yararulesproject_enabled" == "yes" ] ; then
1906 if [ -n "$yararulesproject_dbs" ] ; then
1907 for db in $yararulesproject_dbs ; do
1908 if echo "$db" | $grep_bin -q "/"; then
1909 db=$(echo "$db" | cut -d"/" -f2)
1911 echo "$work_dir_yararulesproject/$db" >> "$current_tmp"
1916 if [ "$additional_enabled" == "yes" ] ; then
1917 if [ -n "$additional_dbs" ] ; then
1918 for db in $additional_dbs ; do
1919 echo "$work_dir_add/$db" >> "$current_tmp"
1924 sort "$current_tmp" > "$current_dbs" 2>/dev/null
1925 rm -f "$current_tmp"
1927 # Remove 3rd-party databases and/or backup files that are no longer being used.
1928 if [ "$remove_disabled_databases" == "yes" ] ; then
1929 previous_dbs="$work_dir_work_configs/previous-dbs.txt"
1930 sort "$current_dbs" > "$previous_dbs" 2>/dev/null
1931 #do not remove the current_dbs
1932 #rm -f "$current_dbs"
1934 db_changes="$work_dir_work_configs/db-changes.txt"
1935 if [ ! -s "$previous_dbs" ] ; then
1936 cp -f "$current_dbs" "$previous_dbs" 2>/dev/null
1938 diff "$current_dbs" "$previous_dbs" 2>/dev/null | $grep_bin '>' | awk '{print $2}' > "$db_changes"
1939 if [ -r "$db_changes" ] ; then
1940 if $grep_bin -vq "bak" "$db_changes" 2>/dev/null ; then
1943 while read -r file ; do
1945 xshok_pretty_echo_and_log "Unused/Disabled file removed: $file"
1946 done < "$db_changes"
1950 # Create "purge.txt" file for package maintainers to support package uninstall.
1951 purge="$work_dir_work_configs/purge.txt"
1952 cp -f "$current_dbs" "$purge"
1954 echo "$work_dir_work_configs/current-dbs.txt"
1955 echo "$work_dir_work_configs/db-changes.txt"
1956 echo "$work_dir_work_configs/last-mbl-update.txt"
1957 echo "$work_dir_work_configs/last-si-update.txt"
1958 echo "$work_dir_work_configs/local.ign"
1959 echo "$work_dir_work_configs/monitor-ign.txt"
1960 echo "$work_dir_work_configs/my-whitelist.ign2"
1961 echo "$work_dir_work_configs/tracker.txt"
1962 echo "$work_dir_work_configs/previous-dbs.txt"
1963 echo "$work_dir_work_configs/scan-test.txt"
1964 echo "$work_dir_work_configs/ss-include-dbs.txt"
1965 echo "$work_dir_work_configs/whitelist.hex"
1966 echo "$work_dir_gpg/publickey.gpg"
1967 echo "$work_dir_gpg/secring.gpg"
1968 echo "$work_dir_gpg/ss-keyring.gpg*"
1969 echo "$work_dir_gpg/trustdb.gpg"
1970 echo "$log_file_path/$log_file_name*"
1971 echo "$work_dir_work_configs/purge.txt"
1974 # Check and save current system time since epoch for time related database downloads.
1975 # However, if unsuccessful, issue a warning that we cannot calculate times since epoch.
1976 if [ -n "$securiteinfo_dbs" ] || [ -n "$malwarepatrol_db" ] ; then
1977 current_time=$(date "+%s" 2> /dev/null)
1978 current_time="${current_time//[^0-9]/}"
1979 current_time="$((current_time + 0))"
1980 if [ "$current_time" -le 0 ] ; then
1981 current_time=$(perl -le print+time 2> /dev/null)
1983 if [ "$current_time" -le 0 ] ; then
1984 xshok_pretty_echo_and_log "WARNING: No support for 'date +%s' or 'perl' was not found , SecuriteInfo and MalwarePatrol updates bypassed" "="
1990 ################################################################
1991 # Check for Sanesecurity database & GPG signature file updates #
1992 ################################################################
1993 if [ "$sanesecurity_enabled" == "yes" ] ; then
1994 if [ -n "$sanesecurity_dbs" ] ; then
1995 ##if [ ${#sanesecurity_dbs[@]} -lt "1" ] ; then ##will not work due to compound array assignment
1996 if [ "$(xshok_array_count "$sanesecurity_dbs")" -lt "1" ] ; then
1997 xshok_pretty_echo_and_log "Failed sanesecurity_dbs config is invalid or not defined - SKIPPING"
1999 if [ -r "$work_dir_work_configs/last-ss-update.txt" ] ; then
2000 last_sanesecurity_update=$(cat "$work_dir_work_configs/last-ss-update.txt")
2002 last_sanesecurity_update="0"
2005 update_interval=$((sanesecurity_update_hours * 3600))
2006 time_interval=$((current_time - last_sanesecurity_update))
2007 if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
2008 echo "$current_time" > "$work_dir_work_configs/last-ss-update.txt"
2009 xshok_pretty_echo_and_log "Sanesecurity Database & GPG Signature File Updates" "="
2010 xshok_pretty_echo_and_log "Checking for Sanesecurity updates..."
2012 sanesecurity_mirror_ips=$(dig +ignore +short "$sanesecurity_url")
2013 #add fallback to host if dig returns no records
2014 if [ "$(xshok_array_count "$sanesecurity_mirror_ips")" -lt 1 ] ; then
2015 sanesecurity_mirror_ips=$(host -t A "$sanesecurity_url" | sed -n '/has address/{s/.*address \([^ ]*\).*/\1/;p;}')
2018 if [ "$(xshok_array_count "$sanesecurity_mirror_ips")" -ge "1" ] ; then
2019 for sanesecurity_mirror_ip in $sanesecurity_mirror_ips ; do
2020 sanesecurity_mirror_name=""
2021 sanesecurity_mirror_name=$(dig +short -x "$sanesecurity_mirror_ip" | command sed 's/\.$//')
2022 #add fallback to host if dig returns no records
2023 if [ "$sanesecurity_mirror_name" == "" ] ; then
2024 sanesecurity_mirror_name=$(host "$sanesecurity_mirror_ip" | sed -n '/name pointer/{s/.*pointer \([^ ]*\).*\.$/\1/;p;}')
2026 sanesecurity_mirror_site_info="$sanesecurity_mirror_name $sanesecurity_mirror_ip"
2027 xshok_pretty_echo_and_log "Sanesecurity mirror site used: $sanesecurity_mirror_site_info"
2028 $rsync_bin $rsync_output_level $no_motd --files-from="$sanesecurity_include_dbs" -ctuz $connect_timeout --timeout="$rsync_max_time" "rsync://$sanesecurity_mirror_ip/sanesecurity" "$work_dir_sanesecurity" 2>/dev/null
2029 if [ "$?" -eq "0" ] ; then #the correct way
2030 sanesecurity_rsync_success="1"
2031 for db_file in $sanesecurity_dbs ; do
2032 if ! cmp -s "$work_dir_sanesecurity/$db_file" "$clam_dbs/$db_file" ; then
2033 xshok_pretty_echo_and_log "Testing updated Sanesecurity database file: $db_file"
2034 if ! $gpg_bin --trust-model always -q --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg/ss-keyring.gpg" --verify "$work_dir_sanesecurity/$db_file.sig" "$work_dir_sanesecurity/$db_file" 2>/dev/null ; then
2035 $gpg_bin --always-trust -q --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg/ss-keyring.gpg" --verify "$work_dir_sanesecurity/$db_file.sig" "$work_dir_sanesecurity/$db_file" 2>/dev/null
2040 if [ "$ret" -eq "0" ] ; then
2041 test "$gpg_silence" = "no" && xshok_pretty_echo_and_log "Sanesecurity GPG Signature tested good on $db_file database"
2044 xshok_pretty_echo_and_log "Sanesecurity GPG Signature test FAILED on $db_file database - SKIPPING"
2047 if [ "$?" -eq "0" ] ; then
2048 db_ext=$(echo "$db_file" | cut -d "." -f2)
2049 if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
2050 if $clamscan_bin --quiet -d "$work_dir_sanesecurity/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
2051 xshok_pretty_echo_and_log "Clamscan reports Sanesecurity $db_file database integrity tested good"
2054 xshok_pretty_echo_and_log "Clamscan reports Sanesecurity $db_file database integrity tested BAD"
2055 if [ "$remove_bad_database" == "yes" ] ; then
2056 if rm -f "$work_dir_sanesecurity/$db_file" ; then
2057 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_sanesecurity/$db_file"
2061 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_sanesecurity/$db_file" "$clam_dbs" 2>/dev/null ; then
2062 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2063 if [ "$selinux_fixes" == "yes" ] ; then
2064 restorecon "$clam_dbs/$db_file"
2066 xshok_pretty_echo_and_log "Successfully updated Sanesecurity production database file: $db_file"
2067 sanesecurity_update=1
2070 xshok_pretty_echo_and_log "Failed to successfully update Sanesecurity production database file: $db_file - SKIPPING"
2074 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_sanesecurity/$db_file" > "$test_dir/$db_file"
2075 $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
2076 $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
2077 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
2078 mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
2079 if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
2080 xshok_pretty_echo_and_log "Clamscan reports Sanesecurity $db_file database integrity tested good"
2083 xshok_pretty_echo_and_log "Clamscan reports Sanesecurity $db_file database integrity tested BAD"
2084 ##DO NOT KILL THIS DB
2086 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
2087 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2088 if [ "$selinux_fixes" == "yes" ] ; then
2089 restorecon "$clam_dbs/$db_file"
2091 xshok_pretty_echo_and_log "Successfully updated Sanesecurity production database file: $db_file"
2092 sanesecurity_update=1
2095 xshok_pretty_echo_and_log "Failed to successfully update Sanesecurity production database file: $db_file - SKIPPING"
2101 if [ "$sanesecurity_update" != "1" ] ; then
2102 xshok_pretty_echo_and_log "No Sanesecurity database file updates found" "-"
2108 xshok_pretty_echo_and_log "Connection to $sanesecurity_mirror_site_info failed - Trying next mirror site..."
2111 if [ "$sanesecurity_rsync_success" != "1" ] ; then
2112 xshok_pretty_echo_and_log "Access to all Sanesecurity mirror sites failed - Check for connectivity issues"
2113 xshok_pretty_echo_and_log "or signature database name(s) misspelled in the script's configuration file."
2116 xshok_pretty_echo_and_log "No Sanesecurity mirror sites found - Check for dns/connectivity issues"
2119 xshok_pretty_echo_and_log "Sanesecurity Database File Updates" "="
2121 time_remaining=$((update_interval - time_interval))
2122 hours_left=$((time_remaining / 3600))
2123 minutes_left=$((time_remaining % 3600 / 60))
2124 xshok_pretty_echo_and_log "$sanesecurity_update_hours hours have not yet elapsed since the last sanesecurity update check"
2125 xshok_pretty_echo_and_log "No update check was performed at this time" "-"
2126 xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
2131 if [ -n "$sanesecurity_dbs" ] ; then
2132 if [ "$remove_disabled_databases" == "yes" ] ; then
2133 xshok_pretty_echo_and_log "Removing disabled Sanesecurity Database files"
2134 for db_file in $sanesecurity_dbs ; do
2135 if [ -r "$work_dir_sanesecurity/$db_file" ] ; then
2136 rm -f "$work_dir_sanesecurity/$db_file"*
2139 if [ -r "$clam_dbs/$db_file" ] ; then
2140 rm -f "$clam_dbs/$db_file"
2148 ##############################################################################################################################################
2149 # Check for updated SecuriteInfo database files every set number of hours as defined in the "USER CONFIGURATION" section of this script #
2150 ##############################################################################################################################################
2151 if [ "$securiteinfo_enabled" == "yes" ] ; then
2152 if [ "$securiteinfo_authorisation_signature" != "YOUR-SIGNATURE-NUMBER" ] ; then
2153 if [ -n "$securiteinfo_dbs" ] ; then
2154 if [ "$(xshok_array_count "$securiteinfo_dbs")" -lt "1" ] ; then
2155 xshok_pretty_echo_and_log "Failed securiteinfo_dbs config is invalid or not defined - SKIPPING"
2157 rm -f "$work_dir_securiteinfo/*.gz"
2158 if [ -r "$work_dir_work_configs/last-si-update.txt" ] ; then
2159 last_securiteinfo_update=$(cat "$work_dir_work_configs/last-si-update.txt")
2161 last_securiteinfo_update="0"
2165 update_interval=$((securiteinfo_update_hours * 3600))
2166 time_interval=$((current_time - last_securiteinfo_update))
2167 if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
2168 echo "$current_time" > "$work_dir_work_configs/last-si-update.txt"
2169 xshok_pretty_echo_and_log "SecuriteInfo Database File Updates" "="
2170 xshok_pretty_echo_and_log "Checking for SecuriteInfo updates..."
2171 securiteinfo_updates="0"
2172 for db_file in $securiteinfo_dbs ; do
2173 if [ "$loop" = "1" ] ; then
2174 xshok_pretty_echo_and_log "---"
2176 xshok_pretty_echo_and_log "Checking for updated SecuriteInfo database file: $db_file"
2177 securiteinfo_db_update="0"
2178 if [ "$wget_bin" != "" ] ; then
2179 $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_securiteinfo/$db_file" "$securiteinfo_url/$securiteinfo_authorisation_signature/$db_file"
2182 $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_securiteinfo/$db_file" "$securiteinfo_url/$securiteinfo_authorisation_signature/$db_file"
2185 if [ "$ret" -eq "0" ] ; then
2187 if ! cmp -s "$work_dir_securiteinfo/$db_file" "$clam_dbs/$db_file" ; then
2188 if [ "$?" -eq "0" ] ; then
2189 db_ext=$(echo "$db_file" | cut -d "." -f2)
2192 xshok_pretty_echo_and_log "Testing updated SecuriteInfo database file: $db_file"
2193 if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ]
2195 if $clamscan_bin --quiet -d "$work_dir_securiteinfo/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
2197 xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo $db_file database integrity tested good"
2200 xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo $db_file database integrity tested BAD"
2201 if [ "$remove_bad_database" == "yes" ] ; then
2202 if rm -f "$work_dir_securiteinfo/$db_file" ; then
2203 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_securiteinfo/$db_file"
2207 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_securiteinfo/$db_file" "$clam_dbs" 2>/dev/null ; then
2208 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2209 if [ "$selinux_fixes" == "yes" ] ; then
2210 restorecon "$clam_dbs/$db_file"
2212 xshok_pretty_echo_and_log "Successfully updated SecuriteInfo production database file: $db_file"
2213 securiteinfo_updates=1
2214 securiteinfo_db_update=1
2217 xshok_pretty_echo_and_log "Failed to successfully update SecuriteInfo production database file: $db_file - SKIPPING"
2220 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_securiteinfo/$db_file" > "$test_dir/$db_file"
2221 $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
2222 $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
2223 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
2224 mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
2225 if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
2227 xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo $db_file database integrity tested good"
2230 xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo $db_file database integrity tested BAD"
2231 rm -f "$work_dir_securiteinfo/$db_file"
2232 if [ "$remove_bad_database" == "yes" ] ; then
2233 if rm -f "$work_dir_securiteinfo/$db_file" ; then
2234 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_securiteinfo/$db_file"
2238 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
2239 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2240 if [ "$selinux_fixes" == "yes" ] ; then
2241 restorecon "$clam_dbs/$db_file"
2243 xshok_pretty_echo_and_log "Successfully updated SecuriteInfo production database file: $db_file"
2244 securiteinfo_updates=1
2245 securiteinfo_db_update=1
2248 xshok_pretty_echo_and_log "Failed to successfully update SecuriteInfo production database file: $db_file - SKIPPING"
2254 xshok_pretty_echo_and_log "Failed connection to $securiteinfo_url - SKIPPED SecuriteInfo $db_file update"
2256 if [ "$securiteinfo_db_update" != "1" ] ; then
2257 xshok_pretty_echo_and_log "No updated SecuriteInfo $db_file database file found" "-"
2260 if [ "$securiteinfo_updates" != "1" ] ; then
2261 xshok_pretty_echo_and_log "No SecuriteInfo database file updates found" "-"
2264 xshok_pretty_echo_and_log "SecuriteInfo Database File Updates" "="
2266 time_remaining=$((update_interval - time_interval))
2267 hours_left=$((time_remaining / 3600))
2268 minutes_left=$((time_remaining % 3600 / 60))
2269 xshok_pretty_echo_and_log "$securiteinfo_update_hours hours have not yet elapsed since the last SecuriteInfo update check"
2270 xshok_pretty_echo_and_log "No update check was performed at this time" "-"
2271 xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
2277 if [ -n "$securiteinfo_dbs" ] ; then
2278 if [ "$remove_disabled_databases" == "yes" ] ; then
2279 xshok_pretty_echo_and_log "Removing disabled SecuriteInfo Database files"
2280 for db_file in $securiteinfo_dbs ; do
2281 if [ -r "$work_dir_securiteinfo/$db_file" ] ; then
2282 rm -f "$work_dir_securiteinfo/$db_file"
2285 if [ -r "$clam_dbs/$db_file" ] ; then
2286 rm -f "$clam_dbs/$db_file"
2295 ##############################################################################################################################################
2296 # Check for updated linuxmalwaredetect database files every set number of hours as defined in the "USER CONFIGURATION" section of this script
2297 ##############################################################################################################################################
2298 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
2299 if [ -n "$linuxmalwaredetect_dbs" ] ; then
2300 if [ "$(xshok_array_count "$linuxmalwaredetect_dbs")" -lt "1" ] ; then
2301 xshok_pretty_echo_and_log "Failed linuxmalwaredetect_dbs config is invalid or not defined - SKIPPING"
2303 rm -f "$work_dir_linuxmalwaredetect/*.gz"
2304 if [ -r "$work_dir_work_configs/last-linuxmalwaredetect-update.txt" ] ; then
2305 last_linuxmalwaredetect_update=$(cat "$work_dir_work_configs/last-linuxmalwaredetect-update.txt")
2307 last_linuxmalwaredetect_update="0"
2311 update_interval=$((linuxmalwaredetect_update_hours * 3600))
2312 time_interval=$((current_time - last_linuxmalwaredetect_update))
2313 if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
2314 echo "$current_time" > "$work_dir_work_configs/last-linuxmalwaredetect-update.txt"
2316 xshok_pretty_echo_and_log "linuxmalwaredetect Database File Updates" "="
2317 xshok_pretty_echo_and_log "Checking for linuxmalwaredetect updates..."
2318 linuxmalwaredetect_updates="0"
2319 for db_file in $linuxmalwaredetect_dbs ; do
2320 if [ "$loop" = "1" ] ; then
2321 xshok_pretty_echo_and_log "---"
2323 xshok_pretty_echo_and_log "Checking for updated linuxmalwaredetect database file: $db_file"
2325 linuxmalwaredetect_db_update="0"
2326 if [ "$wget_bin" != "" ] ; then
2327 $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_linuxmalwaredetect/$db_file" "$linuxmalwaredetect_url/$db_file"
2330 $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_linuxmalwaredetect/$db_file" "$linuxmalwaredetect_url/$db_file"
2333 if [ "$ret" -eq "0" ] ; then
2335 if ! cmp -s "$work_dir_linuxmalwaredetect/$db_file" "$clam_dbs/$db_file" ; then
2336 if [ "$?" -eq "0" ] ; then
2337 db_ext=$(echo "$db_file" | cut -d "." -f2)
2339 xshok_pretty_echo_and_log "Testing updated linuxmalwaredetect database file: $db_file"
2340 if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
2341 if $clamscan_bin --quiet -d "$work_dir_linuxmalwaredetect/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
2343 xshok_pretty_echo_and_log "Clamscan reports linuxmalwaredetect $db_file database integrity tested good"
2346 xshok_pretty_echo_and_log "Clamscan reports linuxmalwaredetect $db_file database integrity tested BAD"
2347 if [ "$remove_bad_database" == "yes" ] ; then
2348 if rm -f "$work_dir_linuxmalwaredetect/$db_file" ; then
2349 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_linuxmalwaredetect/$db_file"
2353 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_linuxmalwaredetect/$db_file" "$clam_dbs" 2>/dev/null ; then
2354 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2355 if [ "$selinux_fixes" == "yes" ] ; then
2356 restorecon "$clam_dbs/local.ign"
2358 xshok_pretty_echo_and_log "Successfully updated linuxmalwaredetect production database file: $db_file"
2359 linuxmalwaredetect_updates=1
2360 linuxmalwaredetect_db_update=1
2363 xshok_pretty_echo_and_log "Failed to successfully update linuxmalwaredetect production database file: $db_file - SKIPPING"
2366 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_linuxmalwaredetect/$db_file" > "$test_dir/$db_file"
2367 $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
2368 $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
2369 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
2370 mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
2371 if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
2372 xshok_pretty_echo_and_log "Clamscan reports linuxmalwaredetect $db_file database integrity tested good"
2375 xshok_pretty_echo_and_log "Clamscan reports linuxmalwaredetect $db_file database integrity tested BAD"
2376 if [ "$remove_bad_database" == "yes" ] ; then
2377 if rm -f "$work_dir_linuxmalwaredetect/$db_file" ; then
2378 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_linuxmalwaredetect/$db_file"
2382 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
2383 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2384 if [ "$selinux_fixes" == "yes" ] ; then
2385 restorecon "$clam_dbs/$db_file"
2387 xshok_pretty_echo_and_log "Successfully updated linuxmalwaredetect production database file: $db_file"
2388 linuxmalwaredetect_updates=1
2389 linuxmalwaredetect_db_update=1
2392 xshok_pretty_echo_and_log "Failed to successfully update linuxmalwaredetect production database file: $db_file - SKIPPING"
2398 xshok_pretty_echo_and_log "WARNING: Failed connection to $linuxmalwaredetect_url - SKIPPED linuxmalwaredetect $db_file update"
2400 if [ "$linuxmalwaredetect_db_update" != "1" ] ; then
2402 xshok_pretty_echo_and_log "No updated linuxmalwaredetect $db_file database file found"
2405 if [ "$linuxmalwaredetect_updates" != "1" ] ; then
2406 xshok_pretty_echo_and_log "No linuxmalwaredetect database file updates found" "-"
2410 xshok_pretty_echo_and_log "linuxmalwaredetect Database File Updates" "="
2412 time_remaining=$((update_interval - time_interval))
2413 hours_left=$((time_remaining / 3600))
2414 minutes_left=$((time_remaining % 3600 / 60))
2415 xshok_pretty_echo_and_log "$linuxmalwaredetect_update_hours hours have not yet elapsed since the last linux malware detect update check"
2416 xshok_pretty_echo_and_log "No update check was performed at this time" "-"
2417 xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
2422 if [ -n "$linuxmalwaredetect_dbs" ] ; then
2423 if [ "$remove_disabled_databases" == "yes" ] ; then
2424 xshok_pretty_echo_and_log "Removing disabled linuxmalwaredetect Database files"
2425 for db_file in $linuxmalwaredetect_dbs ; do
2426 if [ -r "$work_dir_linuxmalwaredetect/$db_file" ] ; then
2427 rm -f "$work_dir_linuxmalwaredetect/$db_file"
2430 if [ -r "$clam_dbs/$db_file" ] ; then
2431 rm -f "$clam_dbs/$db_file"
2440 ##########################################################################################################################################
2441 # Download MalwarePatrol database file every set number of hours as defined in the "USER CONFIGURATION" section of this script. #
2442 ##########################################################################################################################################
2443 if [ "$malwarepatrol_enabled" == "yes" ] ; then
2444 if [ "$malwarepatrol_receipt_code" != "YOUR-RECEIPT-NUMBER" ] ; then
2445 if [ -n "$malwarepatrol_db" ] ; then
2446 if [ -r "$work_dir_work_configs/last-mbl-update.txt" ] ; then
2447 last_malwarepatrol_update=$(cat "$work_dir_work_configs/last-mbl-update.txt")
2449 last_malwarepatrol_update="0"
2452 update_interval=$((malwarepatrol_update_hours * 3600))
2453 time_interval=$((current_time - last_malwarepatrol_update))
2454 if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
2455 echo "$current_time" > "$work_dir_work_configs"/last-mbl-update.txt
2456 xshok_pretty_echo_and_log "Checking for MalwarePatrol updates..."
2457 # Delete the old MBL (mbl.db) database file if it exists and start using the newer
2458 # format (mbl.ndb) database file instead.
2459 # test -e $clam_dbs/$malwarepatrol_db -o -e $clam_dbs/$malwarepatrol_db-bak && rm -f -- "$clam_dbs/mbl.d*"
2461 # remove the .db is th new format if ndb and
2463 if [ "$malwarepatrol_db" == "malwarepatrol.db" ] && [ -f "$clam_dbs/malwarepatrol.ndb" ] ; then
2464 rm "$clam_dbs/malwarepatrol.ndb";
2467 if [ "$malwarepatrol_db" == "malwarepatrol.ndb" ] && [ -f "$clam_dbs/malwarepatrol.db" ] ; then
2468 rm "$clam_dbs/malwarepatrol.db";
2471 xshok_pretty_echo_and_log "MalwarePatrol $db_file Database File Update" "="
2473 malwarepatrol_reloaded=0
2474 if [ "$malwarepatrol_free" == "yes" ] ; then
2475 if [ "$wget_bin" != "" ] ; then
2476 $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_malwarepatrol/$malwarepatrol_db" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code"
2479 $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_malwarepatrol/$malwarepatrol_db" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code"
2482 if [ "$ret" -eq "0" ] ; then
2483 if ! cmp -s "$work_dir_malwarepatrol/$malwarepatrol_db" "$clam_dbs/$malwarepatrol_db" ; then
2484 if [ "$?" -eq "0" ] ; then
2485 malwarepatrol_reloaded=1
2487 malwarepatrol_reloaded=2
2491 malwarepatrol_reloaded=-1
2494 else # The not free branch
2495 if [ "$wget_bin" != "" ] ; then
2496 $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_malwarepatrol/$malwarepatrol_db.md5" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code&hash=1"
2499 $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_malwarepatrol/$malwarepatrol_db.md5" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code&hash=1"
2502 if [ "$ret" -eq "0" ] ; then
2503 if [ -f "$clam_dbs/$malwarepatrol_db" ] ; then
2504 malwarepatrol_md5=$(openssl md5 -r "$clam_dbs/$malwarepatrol_db" 2>/dev/null | cut -d" " -f1)
2505 if [ ! "$malwarepatrol_md5" ] ; then
2506 #fallback for missing -r option
2507 malwarepatrol_md5=$(openssl md5 "$clam_dbs/$malwarepatrol_db" 2>/dev/null | cut -d" " -f2)
2510 malwarepatrol_md5_new=$(cat "$work_dir_malwarepatrol/$malwarepatrol_db.md5")
2511 if [ -n "$malwarepatrol_md5_new" ] && [ "$malwarepatrol_md5" != "$malwarepatrol_md5_new" ] ; then
2512 if [ "$wget_bin" != "" ] ; then
2513 $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_malwarepatrol/$malwarepatrol_db" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code"
2516 $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_malwarepatrol/$malwarepatrol_db" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code"
2519 if [ "$ret" -eq "0" ] ; then
2520 malwarepatrol_reloaded=1
2522 malwarepatrol_reloaded=-1
2525 else # wget MD5 fail
2526 malwarepatrol_reloaded=-1
2530 case "$malwarepatrol_reloaded" in
2531 1) # database was updated, need test and reload
2532 xshok_pretty_echo_and_log "Testing updated MalwarePatrol database file: $malwarepatrol_db"
2533 if $clamscan_bin --quiet -d "$work_dir_malwarepatrol/$malwarepatrol_db" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
2534 xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol $malwarepatrol_db database integrity tested good"
2537 xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol $malwarepatrol_db database integrity tested BAD"
2538 if [ "$remove_bad_database" == "yes" ] ; then
2539 if rm -f "$work_dir_malwarepatrol/$malwarepatrol_db" ; then
2540 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_malwarepatrol/$malwarepatrol_db"
2544 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$malwarepatrol_db" "$clam_dbs/$malwarepatrol_db-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_malwarepatrol/$malwarepatrol_db" "$clam_dbs" 2>/dev/null ; then
2545 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$malwarepatrol_db"
2546 if [ "$selinux_fixes" == "yes" ] ; then
2547 restorecon "$clam_dbs/$malwarepatrol_db"
2549 xshok_pretty_echo_and_log "Successfully updated MalwarePatrol production database file: $malwarepatrol_db"
2552 xshok_pretty_echo_and_log "Failed to successfully update MalwarePatrol production database file: $malwarepatrol_db - SKIPPING"
2554 ;; # The strange case when $? != 0 in the original
2556 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_malwarepatrol/$malwarepatrol_db" > "$test_dir/$malwarepatrol_db"
2557 $clamscan_bin --infected --no-summary -d "$test_dir/$malwarepatrol_db" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
2558 $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$malwarepatrol_db" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
2559 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$malwarepatrol_db" > "$test_dir/$malwarepatrol_db-tmp"
2560 mv -f "$test_dir/$malwarepatrol_db-tmp" "$test_dir/$malwarepatrol_db"
2561 if $clamscan_bin --quiet -d "$test_dir/$malwarepatrol_db" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
2562 xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol $malwarepatrol_db database integrity tested good"
2565 xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol $malwarepatrol_db database integrity tested BAD"
2566 if [ "$remove_bad_database" == "yes" ] ; then
2567 if rm -f "$test_dir/$malwarepatrol_db" ; then
2568 xshok_pretty_echo_and_log "Removed invalid database: $test_dir/$malwarepatrol_db"
2572 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$malwarepatrol_db" "$clam_dbs/$malwarepatrol_db-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$malwarepatrol_db" "$clam_dbs" 2>/dev/null ; then
2573 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$malwarepatrol_db"
2574 if [ "$selinux_fixes" == "yes" ] ; then
2575 restorecon "$clam_dbs/$malwarepatrol_db"
2577 xshok_pretty_echo_and_log "Successfully updated MalwarePatrol production database file: $malwarepatrol_db"
2580 xshok_pretty_echo_and_log "Failed to successfully update MalwarePatrol production database file: $malwarepatrol_db - SKIPPING"
2583 0) # The database did not update
2584 xshok_pretty_echo_and_log "MalwarePatrol signature database ($malwarepatrol_db) did not change - skipping"
2587 xshok_pretty_echo_and_log "WARNING - Failed connection to $malwarepatrol_url - SKIPPED MalwarePatrol $malwarepatrol_db update"
2593 xshok_pretty_echo_and_log "MalwarePatrol Database File Update" "="
2595 time_remaining=$((update_interval - time_interval))
2596 hours_left=$((time_remaining / 3600))
2597 minutes_left=$((time_remaining % 3600 / 60))
2598 xshok_pretty_echo_and_log "$malwarepatrol_update_hours hours have not yet elapsed since the last MalwarePatrol download"
2599 xshok_pretty_echo_and_log "No database download was performed at this time" "-"
2600 xshok_pretty_echo_and_log "Next download will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
2605 if [ -n "$malwarepatrol_db" ] ; then
2606 if [ "$remove_disabled_databases" == "yes" ] ; then
2607 xshok_pretty_echo_and_log "Removing disabled MalwarePatrol Database file"
2608 if [ -r "$work_dir_malwarepatrol/$malwarepatrol_db" ] ; then
2609 rm -f "$work_dir_malwarepatrol/$malwarepatrol_db"
2612 if [ -r "$clam_dbs/$malwarepatrol_db" ] ; then
2613 rm -f "$clam_dbs/$malwarepatrol_db"
2620 ##############################################################################################################################################
2621 # Check for updated yararulesproject database files every set number of hours as defined in the "USER CONFIGURATION" section of this script
2622 ##############################################################################################################################################
2623 if [ "$yararulesproject_enabled" == "yes" ] ; then
2624 if [ -n "$yararulesproject_dbs" ] ; then
2625 if [ "$(xshok_array_count "$yararulesproject_dbs")" -lt "1" ] ; then
2626 xshok_pretty_echo_and_log "Failed yararulesproject_dbs config is invalid or not defined - SKIPPING"
2628 rm -f "$work_dir_yararulesproject/*.gz"
2629 if [ -r "$work_dir_work_configs/last-yararulesproject-update.txt" ] ; then
2630 last_yararulesproject_update=$(cat "$work_dir_work_configs/last-yararulesproject-update.txt")
2632 last_yararulesproject_update="0"
2636 update_interval=$((yararulesproject_update_hours * 3600))
2637 time_interval=$((current_time - last_yararulesproject_update))
2638 if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
2639 echo "$current_time" > "$work_dir_work_configs/last-yararulesproject-update.txt"
2641 xshok_pretty_echo_and_log "Yara-Rules Database File Updates" "="
2642 xshok_pretty_echo_and_log "Checking for yararulesproject updates..."
2643 yararulesproject_updates="0"
2644 for db_file in $yararulesproject_dbs ; do
2645 if echo "$db_file" | $grep_bin -q "/"; then
2646 yr_dir="/"$(echo "$db_file" | cut -d"/" -f1)
2647 db_file=$(echo "$db_file" | cut -d"/" -f2)
2650 if [ "$loop" = "1" ] ; then
2651 xshok_pretty_echo_and_log "---"
2653 xshok_pretty_echo_and_log "Checking for updated yararulesproject database file: $db_file"
2655 yararulesproject_db_update="0"
2656 if [ "$wget_bin" != "" ] ; then
2657 $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_yararulesproject/$db_file" "$yararulesproject_url/$yr_dir/$db_file"
2660 $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_yararulesproject/$db_file" "$yararulesproject_url/$yr_dir/$db_file"
2663 if [ "$ret" -eq "0" ] ; then
2665 if ! cmp -s "$work_dir_yararulesproject/$db_file" "$clam_dbs/$db_file" ; then
2666 if [ "$?" -eq "0" ] ; then
2667 db_ext=$(echo "$db_file" | cut -d "." -f2)
2669 xshok_pretty_echo_and_log "Testing updated yararulesproject database file: $db_file"
2670 if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
2671 if $clamscan_bin --quiet -d "$work_dir_yararulesproject/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
2673 xshok_pretty_echo_and_log "Clamscan reports yararulesproject $db_file database integrity tested good"
2676 xshok_pretty_echo_and_log "Clamscan reports yararulesproject $db_file database integrity tested BAD"
2677 if [ "$remove_bad_database" == "yes" ] ; then
2678 if rm -f "$work_dir_yararulesproject/$db_file" ; then
2679 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_yararulesproject/$db_file"
2683 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_yararulesproject/$db_file" "$clam_dbs" 2>/dev/null ; then
2684 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2685 if [ "$selinux_fixes" == "yes" ] ; then
2686 restorecon "$clam_dbs/$db_file"
2688 xshok_pretty_echo_and_log "Successfully updated yararulesproject production database file: $db_file"
2689 yararulesproject_updates=1
2690 yararulesproject_db_update=1
2693 xshok_pretty_echo_and_log "Failed to successfully update yararulesproject production database file: $db_file - SKIPPING"
2696 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_yararulesproject/$db_file" > "$test_dir/$db_file"
2697 $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
2698 $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
2699 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
2700 mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
2701 if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
2702 xshok_pretty_echo_and_log "Clamscan reports yararulesproject $db_file database integrity tested good"
2705 xshok_pretty_echo_and_log "Clamscan reports yararulesproject $db_file database integrity tested BAD"
2706 if [ "$remove_bad_database" == "yes" ] ; then
2707 if rm -f "$work_dir_yararulesproject/$db_file" ; then
2708 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_yararulesproject/$db_file"
2712 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
2713 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2714 if [ "$selinux_fixes" == "yes" ] ; then
2715 restorecon "$clam_dbs/$db_file"
2717 xshok_pretty_echo_and_log "Successfully updated yararulesproject production database file: $db_file"
2718 yararulesproject_updates=1
2719 yararulesproject_db_update=1
2722 xshok_pretty_echo_and_log "Failed to successfully update yararulesproject production database file: $db_file - SKIPPING"
2728 xshok_pretty_echo_and_log "WARNING: Failed connection to $yararulesproject_url - SKIPPED yararulesproject $db_file update"
2730 if [ "$yararulesproject_db_update" != "1" ] ; then
2731 xshok_pretty_echo_and_log "No updated yararulesproject $db_file database file found"
2734 if [ "$yararulesproject_updates" != "1" ] ; then
2735 xshok_pretty_echo_and_log "No yararulesproject database file updates found" "-"
2739 xshok_pretty_echo_and_log "Yara-Rules Database File Updates" "="
2741 time_remaining=$((update_interval - time_interval))
2742 hours_left=$((time_remaining / 3600))
2743 minutes_left=$((time_remaining % 3600 / 60))
2744 xshok_pretty_echo_and_log "$yararulesproject_update_hours hours have not yet elapsed since the last yararulesproject database update check"
2745 xshok_pretty_echo_and_log "No update check was performed at this time" "-"
2746 xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
2751 if [ -n "$yararulesproject_dbs" ] ; then
2752 if [ "$remove_disabled_databases" == "yes" ] ; then
2753 xshok_pretty_echo_and_log "Removing disabled yararulesproject Database files"
2754 for db_file in $yararulesproject_dbs ; do
2755 if echo "$db_file" | $grep_bin -q "/"; then
2756 db_file=$(echo "$db_file" | cut -d"/" -f2)
2758 if [ -r "$work_dir_yararulesproject/$db_file" ] ; then
2759 rm -f "$work_dir_yararulesproject/$db_file"
2762 if [ -r "$clam_dbs/$db_file" ] ; then
2763 rm -f "$clam_dbs/$db_file"
2771 ##############################################################################################################################################
2772 # Check for updated additional database files every set number of hours as defined in the "USER CONFIGURATION" section of this script
2773 ##############################################################################################################################################
2774 if [ "$additional_enabled" == "yes" ] ; then
2775 if [ -n "$additional_dbs" ] ; then
2776 if [ "$(xshok_array_count "$additional_dbs")" -lt "1" ] ; then
2777 xshok_pretty_echo_and_log "Failed additional_dbs config is invalid or not defined - SKIPPING"
2779 rm -f "$work_dir_add/*.gz"
2780 if [ -r "$work_dir_work_configs/last-additional-update.txt" ] ; then
2781 last_additional_update=$(cat "$work_dir_work_configs/last-additional-update.txt")
2783 last_additional_update="0"
2787 update_interval=$((additional_update_hours * 3600))
2788 time_interval=$((current_time - last_additional_update))
2789 if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
2790 echo "$current_time" > "$work_dir_work_configs/last-additional-update.txt"
2792 xshok_pretty_echo_and_log "Additional Database File Updates" "="
2793 xshok_pretty_echo_and_log "Checking for additional updates..."
2794 additional_updates="0"
2795 for db_url in $additional_dbs ; do
2796 # left for future dir manipulation
2797 # if echo "$db_file" | $grep_bin -q "/"; then
2798 # add_dir="/"$(echo "$db_file" | cut -d"/" -f1)
2799 # db_file=$(echo "$db_file" | cut -d"/" -f2)
2803 db_file=$(basename "$db_url")
2805 if [ "$loop" = "1" ] ; then
2806 xshok_pretty_echo_and_log "---"
2808 xshok_pretty_echo_and_log "Checking for updated additional database file: $db_file"
2810 additional_db_update="0"
2812 if [ "$(echo "$db_url" | cut -d ":" -f1)" = "rsync" ] ; then
2813 $rsync_bin $rsync_output_level $no_motd -ctuz $connect_timeout --timeout="$rsync_max_time" --exclude=*.txt --exclude=*.sha256 --exclude=*.sig --exclude=*.gz "$db_url" "$work_dir_add" 2>/dev/null
2816 if [ "$wget_bin" != "" ] ; then
2817 $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_add/$db_file" "$db_url"
2820 $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_add/$db_file" "$db_url"
2825 ##this needs enhancement for rsync, as it will only work with single files... maybe better to process each file inside work_dir_add in its own for loop.
2826 if [ "$ret" -eq "0" ] ; then
2828 if ! cmp -s "$work_dir_add/$db_file" "$clam_dbs/$db_file" ; then
2829 if [ "$?" -eq "0" ] ; then
2830 db_ext=$(echo "$db_file" | cut -d "." -f2)
2832 xshok_pretty_echo_and_log "Testing updated additional database file: $db_file"
2833 if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
2834 if $clamscan_bin --quiet -d "$work_dir_add/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
2836 xshok_pretty_echo_and_log "Clamscan reports additional $db_file database integrity tested good"
2839 xshok_pretty_echo_and_log "Clamscan reports additional $db_file database integrity tested BAD"
2840 if [ "$remove_bad_database" == "yes" ] ; then
2841 if rm -f "$work_dir_add/$db_file" ; then
2842 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_add/$db_file"
2846 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_add/$db_file" "$clam_dbs" 2>/dev/null ; then
2847 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2848 if [ "$selinux_fixes" == "yes" ] ; then
2849 restorecon "$clam_dbs/$db_file"
2851 xshok_pretty_echo_and_log "Successfully updated additional production database file: $db_file"
2852 additional_updates=1
2853 additional_db_update=1
2856 xshok_pretty_echo_and_log "Failed to successfully update additional production database file: $db_file - SKIPPING"
2859 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_add/$db_file" > "$test_dir/$db_file"
2860 $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
2861 $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
2862 $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
2863 mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
2864 if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
2865 xshok_pretty_echo_and_log "Clamscan reports additional $db_file database integrity tested good"
2868 xshok_pretty_echo_and_log "Clamscan reports additional $db_file database integrity tested BAD"
2869 if [ "$remove_bad_database" == "yes" ] ; then
2870 if rm -f "$work_dir_add/$db_file" ; then
2871 xshok_pretty_echo_and_log "Removed invalid database: $work_dir_add/$db_file"
2875 fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
2876 perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
2877 if [ "$selinux_fixes" == "yes" ] ; then
2878 restorecon "$clam_dbs/$db_file"
2880 xshok_pretty_echo_and_log "Successfully updated additional production database file: $db_file"
2881 additional_updates=1
2882 additional_db_update=1
2885 xshok_pretty_echo_and_log "Failed to successfully update additional production database file: $db_file - SKIPPING"
2891 xshok_pretty_echo_and_log "WARNING: Failed connection to $additional_url - SKIPPED additional $db_file update"
2893 if [ "$additional_db_update" != "1" ] ; then
2894 xshok_pretty_echo_and_log "No updated additional $db_file database file found"
2897 if [ "$additional_updates" != "1" ] ; then
2898 xshok_pretty_echo_and_log "No additional database file updates found" "-"
2902 xshok_pretty_echo_and_log "Additional Database File Updates" "="
2904 time_remaining=$((update_interval - time_interval))
2905 hours_left=$((time_remaining / 3600))
2906 minutes_left=$((time_remaining % 3600 / 60))
2907 xshok_pretty_echo_and_log "$additional_update_hours hours have not yet elapsed since the last additional database update check"
2908 xshok_pretty_echo_and_log "No update check was performed at this time" "-"
2909 xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
2914 if [ -n "$additional_dbs" ] ; then
2915 if [ "$remove_disabled_databases" == "yes" ] ; then
2916 xshok_pretty_echo_and_log "Removing disabled additional Database files"
2917 for db_file in $additional_dbs ; do
2918 if echo "$db_file" | $grep_bin -q "/"; then
2919 db_file=$(echo "$db_file" | cut -d"/" -f2)
2921 if [ -r "$work_dir_add/$db_file" ] ; then
2922 rm -f "$work_dir_add/$db_file"
2925 if [ -r "$clam_dbs/$db_file" ] ; then
2926 rm -f "$clam_dbs/$db_file"
2934 ###################################################
2935 # Generate whitelists
2936 ###################################################
2937 # Check to see if the local.ign file exists, and if it does, check to see if any of the script
2938 # added bypass entries can be removed due to offending signature modifications or removals.
2939 if [ -r "$clam_dbs/local.ign" ] && [ -s "$work_dir_work_configs/monitor-ign.txt" ] ; then
2941 cd "$clam_dbs" || exit
2942 cp -f local.ign "$work_dir_work_configs/local.ign"
2943 cp -f "$work_dir_work_configs/monitor-ign.txt" "$work_dir_work_configs/monitor-ign-old.txt"
2945 xshok_pretty_echo_and_log "" "=" "80"
2946 while read -r entry ; do
2947 sig_file=$(echo "$entry" | tr -d "\r" | awk -F ":" '{print $1}')
2948 sig_hex=$(echo "$entry" | tr -d "\r" | awk -F ":" '{print $NF}')
2949 sig_name_old=$(echo "$entry" | tr -d "\r" | awk -F ":" '{print $3}')
2950 sig_ign_old=$($grep_bin ":$sig_name_old" "$work_dir_work_configs/local.ign")
2951 sig_old=$(echo "$entry" | tr -d "\r" | cut -d ":" -f3-)
2952 sig_new=$($grep_bin -hwF ":$sig_hex" "$sig_file" | tr -d "\r" 2>/dev/null)
2953 sig_mon_new=$($grep_bin -HwF -n ":$sig_hex" "$sig_file" | tr -d "\r")
2954 if [ -n "$sig_new" ] ; then
2955 if [ "$sig_old" != "$sig_new" ] || [ "$entry" != "$sig_mon_new" ] ; then
2956 sig_name_new=$(echo "$sig_new" | tr -d "\r" | awk -F ":" '{print $1}')
2957 sig_ign_new=$(echo "$sig_mon_new" | cut -d ":" -f1-3)
2958 perl -i -ne "print unless /$sig_ign_old/" "$work_dir_work_configs/monitor-ign.txt"
2959 echo "$sig_mon_new" >> "$work_dir_work_configs/monitor-ign.txt"
2960 perl -p -i -e "s/$sig_ign_old/$sig_ign_new/" "$work_dir_work_configs/local.ign"
2961 xshok_pretty_echo_and_log "$sig_name_old hexadecimal signature is unchanged, however signature name and/or line placement"
2962 xshok_pretty_echo_and_log "in $sig_file has changed to $sig_name_new - updated local.ign to reflect this change."
2966 perl -i -ne "print unless /$sig_ign_old/" "$work_dir_work_configs/monitor-ign.txt" "$work_dir_work_configs/local.ign"
2968 xshok_pretty_echo_and_log "$sig_name_old signature has been removed from $sig_file, entry removed from local.ign."
2971 done < "$work_dir_work_configs/monitor-ign-old.txt"
2972 if [ "$ign_updated" = "1" ] ; then
2973 if $clamscan_bin --quiet -d "$work_dir_work_configs/local.ign" "$work_dir_work_configs/scan-test.txt"
2975 if $rsync_bin -pcqt "$work_dir_work_configs/local.ign" "$clam_dbs"
2977 perms chown -f "$clam_user:$clam_group" "$clam_dbs/local.ign"
2978 perms chmod -f 0644 "$clam_dbs/local.ign" "$work_dir_work_configs/monitor-ign.txt"
2979 if [ "$selinux_fixes" == "yes" ] ; then
2980 restorecon "$clam_dbs/local.ign"
2984 xshok_pretty_echo_and_log "Failed to successfully update local.ign file - SKIPPING"
2987 xshok_pretty_echo_and_log "Clamscan reports local.ign database integrity is bad - SKIPPING"
2990 xshok_pretty_echo_and_log "No whitelist signature changes found in local.ign" "="
2994 # Check to see if my-whitelist.ign2 file exists, and if it does, check to see if any of the script
2995 # added whitelist entries can be removed due to offending signature modifications or removals.
2996 if [ -r "$clam_dbs/my-whitelist.ign2" ] && [ -s "$work_dir_work_configs/tracker.txt" ] ; then
2998 cd "$clam_dbs" || exit
2999 cp -f my-whitelist.ign2 "$work_dir_work_configs/my-whitelist.ign2"
3001 xshok_pretty_echo_and_log "" "=" "80"
3003 while read -r entry ; do
3004 sig_file=$(echo "$entry" | cut -d ":" -f1)
3005 sig_full=$(echo "$entry" | cut -d ":" -f2-)
3006 sig_name=$(echo "$entry" | cut -d ":" -f2)
3007 if ! $grep_bin -F "$sig_full" "$sig_file" > /dev/null 2>&1 ; then
3008 perl -i -ne "print unless /$sig_name$/" "$work_dir_work_configs/my-whitelist.ign2"
3009 perl -i -ne "print unless /:$sig_name:/" "$work_dir_work_configs/tracker-tmp.txt"
3011 xshok_pretty_echo_and_log "$sig_name signature no longer exists in $sig_file, whitelist entry removed from my-whitelist.ign2"
3014 done < "$work_dir_work_configs/tracker.txt"
3015 mv -f "$work_dir_work_configs/tracker-tmp.txt" "$work_dir_work_configs/tracker.txt"
3017 xshok_pretty_echo_and_log "" "=" "80"
3018 if [ "$ign2_updated" = "1" ]
3020 if $clamscan_bin --quiet -d "$work_dir_work_configs/my-whitelist.ign2" "$work_dir_work_configs/scan-test.txt"
3022 if $rsync_bin -pcqt "$work_dir_work_configs/my-whitelist.ign2" "$clam_dbs"
3024 perms chown -f "$clam_user:$clam_group" "$clam_dbs/my-whitelist.ign2"
3025 perms chmod -f 0644 "$clam_dbs/my-whitelist.ign2" "$work_dir_work_configs/tracker.txt"
3026 if [ "$selinux_fixes" == "yes" ] ; then
3027 restorecon "$clam_dbs/my-whitelist.ign2"
3028 restorecon "$work_dir_work_configs/tracker.txt"
3032 xshok_pretty_echo_and_log "Failed to successfully update my-whitelist.ign2 file - SKIPPING"
3035 xshok_pretty_echo_and_log "Clamscan reports my-whitelist.ign2 database integrity is bad - SKIPPING"
3038 xshok_pretty_echo_and_log "No whitelist signature changes found in my-whitelist.ign2"
3042 # Check for non-matching whitelist.hex signatures and remove them from the whitelist file (signature modified or removed).
3043 if [ -n "$ham_dir" ] ; then
3044 if [ -r "$work_dir_work_configs/whitelist.hex" ] ; then
3045 $grep_bin -h -f "$work_dir_work_configs/whitelist.hex" "$work_dir"/*/*.ndb | cut -d "*" -f2 | tr -d "\r" | sort | uniq > "$work_dir_work_configs/whitelist.tmp"
3046 mv -f "$work_dir_work_configs/whitelist.tmp" "$work_dir_work_configs/whitelist.hex"
3047 rm -f "$work_dir_work_configs/whitelist.txt"
3048 rm -f "$test_dir"/*.*
3049 xshok_pretty_echo_and_log "WARNING: Signature(s) triggered on HAM directory scan - signature(s) removed" "*"
3051 xshok_pretty_echo_and_log "No signatures triggered on HAM directory scan" "="
3055 # Set appropriate directory and file permissions to all production signature files
3056 # and set file access mode to 0644 on all working directory files.
3058 if [ "$setmode" = "yes" ] ; then
3059 xshok_pretty_echo_and_log "Setting permissions and ownership" "="
3060 perms chown -f -R "$clam_user:$clam_group" "$work_dir"
3061 if ! find "$work_dir" -type f -exec chmod -f 0644 {} + 2>/dev/null ; then
3062 if ! find "$work_dir" -type f -print0 | xargs -0 chmod -f 0644 2>/dev/null ; then
3063 if ! find "$work_dir" -type f -print0 | xargs chmod -f 0644 2>/dev/null ; then
3064 find "$work_dir" -type f -exec chmod -f 0644 {} \;
3069 # If enabled, set file access mode for all production signature database files to 0644.
3070 perms chown -f -R "$clam_user:$clam_group" "$clam_dbs"
3071 if ! find "$clam_dbs" -type f -exec chmod -f 0644 {} + 2>/dev/null ; then
3072 if ! find "$clam_dbs" -type f -print0 | xargs -0 chmod -f 0644 2>/dev/null ; then
3073 if ! find "$clam_dbs" -type f -print0 | xargs chmod -f 0644 2>/dev/null ; then
3074 find "$clam_dbs" -type f -exec chmod -f 0644 {} \;
3080 # Reload all clamd databases
3083 xshok_pretty_echo_and_log "Issue tracker : https://github.com/extremeshok/clamav-unofficial-sigs/issues" "-"
3089 # And lastly we exit, Note: the exit is always on the 2nd last line