1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
#!/bin/bash -ue
LOGFILE="$(mktemp)"
STATE="$(mktemp -d)"
#shellcheck disable=SC2064 # we want to expand variables now
trap "rm -rf '$LOGFILE' '$STATE'" 0 INT QUIT ABRT PIPE TERM
chown root:adm "$LOGFILE"
chmod 0640 "$LOGFILE"
chown logcheck:logcheck "$STATE"
chmod 0750 "$STATE"
STATUS="PASS"
# usage: run_test "name of test - description" \
# ./expected_output.file <expected exit status> \
# command_to_test arg1 arg2...
# The global variable "$STATUS" is set to "FAIL" if this test fails
run_test(){
local name="$1"
local expected_file="$2"
local expected_exit="$3"
shift 3
local my_status=""
local diff="" code="0"
"$@" > ./actual_file 2>&1 || code="$?"
diff="$(diff -u -- "$expected_file" ./actual_file 2>&1 || :)"
if [ "$code" != "$expected_exit" ]; then
my_status="ERROR (expected exit: $expected_exit, actual: $code)"
elif [ -z "$diff" ]; then
my_status="PASS"
else
my_status="FAIL"
fi
echo "** $my_status: $name"
if [ "$my_status" != "PASS" ]; then
STATUS=FAIL
cat <<EOF
== [ EXPECTED: $name ] ======
$(< "$expected_file")
=============================
== [ ACTUAL: $name ] ========
$(< ./actual_file)
=============================
== [ DIFF: $name ] ==========
$diff
=============================
EOF
fi
}
# for debugging only
Xrun_test(){
echo "** DISABLED: $1"
}
cat > "${LOGFILE}" <<EOF
Jan 31 06:51:07 debian-sid-amd64 su: pam_unix(su-l:auth) failure; logname=testuser uid=1000 euid=0 tty=pts/7 ruser=testuser rhost= user=root
Jan 31 06:51:09 debian-sid-amd64 su: FAILED SU (to root) testuser on pts/7
Jan 31 07:15:01 debian-sid-amd64 CRON[588228]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Jan 31 07:17:01 debian-sid-amd64 CRON[588240]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
EOF
cat > as-root<<EOF
logcheck should not be run as root. Use su to invoke logcheck:
su -s /bin/bash -c "/usr/sbin/logcheck" logcheck
Or use sudo: sudo -u logcheck logcheck.
EOF
run_test "needs-root" ./as-root 1 logcheck
cat > as-root-with-args<<EOF
logcheck should not be run as root. Use su to invoke logcheck:
su -s /bin/bash -c "/usr/sbin/logcheck arg1 arg2" logcheck
Or use sudo: sudo -u logcheck logcheck arg1 arg2.
EOF
run_test "needs-root-with-args" ./as-root-with-args 1 logcheck arg1 arg2
cat > expected <<EOF
Error: /no-such-list does not exist or could not be read
EOF
run_test "-L /no-such-list" expected 1 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -L /no-such-list -D /dev/null" \
logcheck
cat > expected <<EOF
Error: E: File could not be read: /no-such-file
EOF
echo "/no-such-file" > list
run_test "-L list where list contains unreadable file" expected 1 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -L ./list -D /dev/null" \
logcheck
## Testing of output
run_test "logcheck (1a: with header disabled)" \
./test/results/intro/disabled 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/intro/files -D /dev/null -c test/conf/intro-disabled -r test/rulefiles" \
logcheck
run_test "logcheck (repeating 1a: no more results)" \
./test/results/empty 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/intro/files -D /dev/null -c test/conf/intro-disabled -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (1b: with header enabled)" \
./test/results/intro/enabled 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/intro/files -D /dev/null -c test/conf/intro-enabled -r test/rulefiles" \
logcheck
run_test "logcheck (repeating 1b: no more results)" \
./test/results/empty 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/intro/files -D /dev/null -c test/conf/intro-enabled -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (1c: INTRO=yes is the same as INTRO=1 - both enable the intro)" \
./test/results/intro/enabled 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/intro/files -D /dev/null -c test/conf/intro-yes -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (1d: INTRO=no is treated the same as disabling the intro)" \
./test/results/intro/disabled 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/intro/files -D /dev/null -c test/conf/intro-no -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (2a: with cracking-ignore enabled - just one line is flagged)" \
./test/results/cracking-ignore/enabled 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/cracking-ignore/files -D /dev/null -c test/conf/cracking-ignore-enabled -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (2b: with cracking-ignore disabled - both lines are flagged)" \
./test/results/cracking-ignore/disabled 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/cracking-ignore/files -D /dev/null -c test/conf/intro-enabled -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (3: violations.ignore.d - only one of the 2 lines is flagged)" \
./test/results/violations.ignore.d/test 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -L test/logs/violations.ignore.d/files -D /dev/null -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (4a: reportlevel - paranoid)" \
./test/results/reportlevel/paranoid 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -c test/conf/paranoid -L test/logs/reportlevel/files -D /dev/null -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (4b: reportlevel - server)" \
./test/results/reportlevel/server 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -c test/conf/server -L test/logs/reportlevel/files -D /dev/null -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (4c: reportlevel - workstation)" \
./test/results/reportlevel/workstation 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -c test/conf/workstation -L test/logs/reportlevel/files -D /dev/null -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
run_test "logcheck (5: all - paranoid)" \
./test/results/all/paranoid 0 \
su -s /bin/bash -c \
"/usr/sbin/logcheck -o -S '$STATE' -c test/conf/paranoid -L test/logs/all/files -D /dev/null -r test/rulefiles" \
logcheck
rm -f "$STATE"/offset*
printf "This email is sent by logcheck. If you no longer wish to receive
such mail, you can either uninstall the logcheck package or modify
its configuration file (/etc/logcheck/logcheck.conf).
Security Events for su
=-=-=-=-=-=-=-=-=-=-=-
Jan 31 06:51:07 debian-sid-amd64 su: pam_unix(su-l:auth) failure; logname=testuser uid=1000 euid=0 tty=pts/7 ruser=testuser rhost= user=root
Jan 31 06:51:09 debian-sid-amd64 su: FAILED SU (to root) testuser on pts/7
\n" > expected
rm -f "$STATE"/offset*
run_test "logcheck (actual rules and config)" expected 0 \
su -s /bin/bash -c "/usr/sbin/logcheck -o -l '$LOGFILE' -S '$STATE'" logcheck
if [ "$STATUS" = "PASS" ]; then
echo "* $0: PASS"
exit 0
else
echo "* $0: $STATUS"
exit 1
fi
|