source: trunk/test/testrun_1.sh@ 159

Last change on this file since 159 was 138, checked in by rainer, 17 years ago

More fixes for compile and runtime errors.

File size: 30.0 KB
Line 
1#! /bin/sh
2
3#
4# Copyright Rainer Wichmann (2006)
5#
6# License Information:
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20#
21
22RCFILE="$PW_DIR/testrc_1.dyn"; export RCFILE
23LOGFILE="$PW_DIR/.samhain_log"; export LOGFILE
24
25# --enable-login-watch --enable-xml-log
26# --enable-debug --enable-suidcheck --with-prelude
27
28BUILDOPTS="--quiet $TRUST --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file --enable-debug"
29export BUILDOPTS
30
31BASE="${PW_DIR}/testrun_testdata"; export BASE
32TDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c"; export TDIRS
33TFILES="x y z"; export TFILES
34
35###########################################################
36#
37# ---- [Define tests here] ----
38#
39
40# 1 for testing new tests
41testrun1_setup=0
42
43MAXTEST=13; export MAXTEST
44
45test_dirs () {
46 for ff in $CDIRS; do
47 #
48 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
49 if [ $? -ne 0 ]; then
50 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
51 return 1
52 fi
53 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
54 if [ $tmp -ne 1 ]; then
55 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
56 fi
57 #
58 done
59 for ff in $NDIRS; do
60 #
61 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
62 if [ $? -eq 0 ]; then
63 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
64 return 1
65 fi
66 done
67}
68
69#
70# combine file check schedule with one-shot mode
71#
72TESTPOLICY_13="
73[ReadOnly]
74dir=99${BASE}
75"
76
77mod_testdata_13 () {
78 one_sec_sleep
79 echo "foobar" >"${BASE}/c/x"; # bad
80 chmod 0555 "${BASE}/a/y"; # bad
81 ORIGINAL='SetFilecheckTime=60'
82 REPLACEMENT='FileCheckScheduleOne = 6 12 * * *'
83 ex -s $RCFILE <<EOF
84%s/${ORIGINAL}/${REPLACEMENT}/g
85wq
86EOF
87}
88
89chk_testdata_13 () {
90 # CDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
91 tmp=`grep CRIT $LOGFILE | wc -l`
92 if [ $tmp -ne 2 ]; then
93 [ -z "$verbose" ] || log_msg_fail "policy count";
94 return 1
95 fi
96 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/c/x" $LOGFILE >/dev/null 2>&1
97 if [ $? -ne 0 ]; then
98 [ -z "$verbose" ] || log_msg_fail "${BASE}/c/x";
99 return 1
100 fi
101 egrep "CRIT.*POLICY \[ReadOnly\] -----M--T-.*${BASE}/a/y" $LOGFILE >/dev/null 2>&1
102 if [ $? -ne 0 ]; then
103 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/y";
104 return 1
105 fi
106 CDIRS="a a/a a/b a/c c b a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
107 NDIRS="";
108 test_dirs;
109 return $?
110}
111
112TESTPOLICY_12="
113[ReadOnly]
114dir=99${BASE}
115[IgnoreAll]
116dir=-1${BASE}/b
117[Attributes]
118dir=1${BASE}/a
119"
120
121mod_testdata_12 () {
122 one_sec_sleep
123 echo "foobar" >"${BASE}/b/x"; # ok
124 echo "foobar" >"${BASE}/c/x"; # bad
125 echo "foobar" >"${BASE}/a/x"; # ok
126 chmod 0555 "${BASE}/a/a/x"; # bad
127 chmod 0555 "${BASE}/a/a/a/x";# ok
128 chmod 0555 "${BASE}/a/y"; # bad
129}
130
131chk_testdata_12 () {
132 # CDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
133 tmp=`grep CRIT $LOGFILE | wc -l`
134 if [ $tmp -ne 3 ]; then
135 [ -z "$verbose" ] || log_msg_fail "policy count";
136 return 1
137 fi
138 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/c/x" $LOGFILE >/dev/null 2>&1
139 if [ $? -ne 0 ]; then
140 [ -z "$verbose" ] || log_msg_fail "${BASE}/c/x";
141 return 1
142 fi
143 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/a/x" $LOGFILE >/dev/null 2>&1
144 if [ $? -ne 0 ]; then
145 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/x";
146 return 1
147 fi
148 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/y" $LOGFILE >/dev/null 2>&1
149 if [ $? -ne 0 ]; then
150 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/y";
151 return 1
152 fi
153 CDIRS="a a/a a/b a/c c";
154 NDIRS="b a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
155 test_dirs;
156 return $?
157}
158
159#
160# --- ACL/SELinux test case
161#
162TESTPOLICY_11="
163[ReadOnly]
164dir=99${BASE}
165[IgnoreAll]
166dir=-1${BASE}/b
167[Attributes]
168dir=1${BASE}/a
169[Misc]
170UseSelinuxCheck = no
171UseAclCheck = no
172"
173
174mod_testdata_11 () {
175 one_sec_sleep
176 setfacl -m 'user:nobody:r--' "${BASE}/b/x"; # ok (ign)
177 setfacl -m 'user:nobody:r--' "${BASE}/c/x"; # bad
178 setfacl -m 'user:nobody:r--' "${BASE}/a/x"; # bad
179 setfattr -n 'security.selinux' -v "system_u:object_r:etc_t\000" "${BASE}/b/y"; # ok (ign)
180 setfattr -n 'security.selinux' -v "system_u:object_r:etc_t\000" "${BASE}/a/a/a/x";# ok (depth)
181 setfattr -n 'security.selinux' -v "system_u:object_r:etc_t\000" "${BASE}/a/x"; # bad
182 setfattr -n 'security.selinux' -v "system_u:object_r:etc_t\000" "${BASE}/a/y"; # bad
183}
184
185chk_testdata_11 () {
186 # CDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
187 tmp=`grep CRIT $LOGFILE | wc -l`
188 if [ $tmp -ne 1 ]; then
189 [ -z "$verbose" ] || log_msg_fail "policy count";
190 return 1
191 fi
192 egrep "CRIT.*POLICY \[ReadOnly\] --------T-.*${BASE}/c/x" $LOGFILE >/dev/null 2>&1
193 if [ $? -ne 0 ]; then
194 [ -z "$verbose" ] || log_msg_fail "${BASE}/c/x";
195 return 1
196 fi
197 CDIRS="a a/a a/b a/c c";
198 NDIRS="b a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
199 test_dirs;
200 return $?
201}
202
203TESTPOLICY_10="
204[ReadOnly]
205dir=99${BASE}
206[IgnoreAll]
207dir=-1${BASE}/b
208[Attributes]
209dir=1${BASE}/a
210"
211
212mod_testdata_10 () {
213 one_sec_sleep
214 setfacl -m 'user:nobody:r--' "${BASE}/b/x"; # ok (ign)
215 setfacl -m 'user:nobody:r--' "${BASE}/c/x"; # bad
216 setfacl -m 'user:nobody:r--' "${BASE}/a/x"; # bad
217 setfattr -n 'security.selinux' -v "system_u:object_r:etc_t\000" "${BASE}/b/y"; # ok (ign)
218 setfattr -n 'security.selinux' -v "system_u:object_r:etc_t\000" "${BASE}/a/a/a/x";# ok (depth)
219 setfattr -n 'security.selinux' -v "system_u:object_r:etc_t\000" "${BASE}/a/x"; # bad
220 setfattr -n 'security.selinux' -v "system_u:object_r:etc_t\000" "${BASE}/a/y"; # bad
221}
222
223chk_testdata_10 () {
224 # CDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
225 tmp=`grep CRIT $LOGFILE | wc -l`
226 if [ $tmp -ne 3 ]; then
227 [ -z "$verbose" ] || log_msg_fail "policy count";
228 return 1
229 fi
230 egrep "CRIT.*POLICY \[ReadOnly\] -----M--T-.*${BASE}/c/x" $LOGFILE >/dev/null 2>&1
231 if [ $? -ne 0 ]; then
232 [ -z "$verbose" ] || log_msg_fail "${BASE}/c/x";
233 return 1
234 fi
235 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/x" $LOGFILE >/dev/null 2>&1
236 if [ $? -ne 0 ]; then
237 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/x";
238 return 1
239 fi
240 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/y" $LOGFILE >/dev/null 2>&1
241 if [ $? -ne 0 ]; then
242 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/y";
243 return 1
244 fi
245 CDIRS="a a/a a/b a/c c";
246 NDIRS="b a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
247 test_dirs;
248 return $?
249}
250
251TESTPOLICY_9="
252[ReadOnly]
253dir=0${BASE}/b
254[Attributes]
255dir=2${BASE}/a/a
256"
257
258mod_testdata_9 () {
259 echo "foobar" >"${BASE}/b/x";
260 echo "foobar" >"${BASE}/a/x";
261 echo "foobar" >"${BASE}/x";
262}
263
264chk_testdata_9 () {
265 # CDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
266 tmp=`grep CRIT $LOGFILE | wc -l`
267 if [ $tmp -ne 1 ]; then
268 [ -z "$verbose" ] || log_msg_fail "policy count";
269 return 1
270 fi
271 CDIRS="b a/a a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
272 NDIRS="a c a/b a/c";
273 test_dirs;
274 return $?
275}
276
277TESTPOLICY_8="
278[ReadOnly]
279dir=1${BASE}
280[Attributes]
281dir=1${BASE}/a/a
282"
283
284mod_testdata_8 () {
285 echo "foobar" >"${BASE}/a/x";
286 chmod 0555 "${BASE}/a/a/a/b/x";
287}
288
289chk_testdata_8 () {
290 # CDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c";
291 tmp=`grep CRIT $LOGFILE | wc -l`
292 if [ $tmp -ne 1 ]; then
293 [ -z "$verbose" ] || log_msg_fail "policy count";
294 return 1
295 fi
296 CDIRS="a b c a/a a/a/a a/a/b a/a/c";
297 NDIRS="a/b a/c a/a/a/a a/a/a/b a/a/a/c";
298 test_dirs;
299 return $?
300}
301
302
303TESTPOLICY_7="
304[ReadOnly]
305dir=${BASE}
306[Attributes]
307dir=${BASE}/a/a
308[GrowingLogFiles]
309dir=${BASE}/a/a/a
310[IgnoreAll]
311file=${BASE}/a/a/a/z
312dir=${BASE}/b
313[Misc]
314IgnoreMissing=${BASE}/a/[[:alnum:]]+/[[:alnum:]]+\$
315IgnoreAdded=${BASE}/a/(b|c)/[[:alnum:]]+\$
316"
317
318mod_testdata_7 () {
319 one_sec_sleep
320 echo "foobar" >"${BASE}/a/a/a/z" # ok
321 echo "foobar" >"${BASE}/a/a/a/x" # bad
322 echo "foobar" >"${BASE}/a/a/x" # ok
323 echo "foobar" >"${BASE}/a/x" # bad
324 chmod 0555 "${BASE}/a" # bad
325 chmod 0555 "${BASE}/b" # ok
326
327 rm "${BASE}/a/c/z"
328 touch "${BASE}/a/c/zz2"
329}
330
331
332chk_testdata_7 () {
333 tmp=`grep CRIT $LOGFILE | wc -l`
334 if [ $tmp -ne 4 ]; then
335 [ -z "$verbose" ] || log_msg_fail "policy count";
336 return 1
337 fi
338 egrep "ERROR.*POLICY MISSING.*${BASE}/a/c/z" $LOGFILE >/dev/null 2>&1
339 if [ $? -eq 0 ]; then
340 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/c/z";
341 return 1
342 fi
343 egrep "CRIT.*POLICY ADDED.*${BASE}/a/c/zz2" $LOGFILE >/dev/null 2>&1
344 if [ $? -eq 0 ]; then
345 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/c/zz2";
346 return 1
347 fi
348 egrep "CRIT.*POLICY \[GrowingLogs\] C--------S.*${BASE}/a/a/a/x" $LOGFILE >/dev/null 2>&1
349 if [ $? -ne 0 ]; then
350 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/a/x";
351 return 1
352 fi
353 egrep "CRIT.*POLICY \[ReadOnly\] -----M--T-.*${BASE}/a" $LOGFILE >/dev/null 2>&1
354 if [ $? -ne 0 ]; then
355 [ -z "$verbose" ] || log_msg_fail "${BASE}/a";
356 return 1
357 fi
358 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/x" $LOGFILE >/dev/null 2>&1
359 if [ $? -ne 0 ]; then
360 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/x";
361 return 1
362 fi
363}
364
365
366TESTPOLICY_6="
367[ReadOnly]
368dir=${BASE}
369[Attributes]
370file=${BASE}/a/y
371file=${BASE}/b/y
372file=${BASE}/c/y
373file=${BASE}/a/a/y
374file=${BASE}/a/b/y
375file=${BASE}/a/c/y
376file=${BASE}/a/a/a/y
377file=${BASE}/a/a/b/y
378file=${BASE}/a/a/c/y
379file=${BASE}/a/a/a/a/y
380file=${BASE}/a/a/a/b/y
381file=${BASE}/a/a/a/c/y
382"
383
384mod_testdata_6 () {
385 one_sec_sleep
386 for ff in $TDIRS; do
387 echo "foobar" >"${BASE}/${ff}/x"
388 chmod 0555 "${BASE}/${ff}/y"
389 echo "foobar" >"${BASE}/${ff}/z"
390 done
391}
392
393chk_testdata_6 () {
394 count6=0
395 for ff in $TDIRS; do
396 #
397 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
398 if [ $? -ne 0 ]; then
399 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
400 return 1
401 fi
402 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
403 if [ $tmp -ne 1 ]; then
404 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
405 fi
406 #
407 for gg in $TFILES; do
408 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
409 if [ $? -ne 0 ]; then
410 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
411 fi
412 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
413 if [ $tmp -ne 1 ]; then
414 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
415 fi
416 done
417 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/${ff}/x" $LOGFILE >/dev/null 2>&1
418 if [ $? -ne 0 ]; then
419 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/x";
420 return 1
421 fi
422 let "count6 = count6 + 1" >/dev/null
423 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/${ff}/z" $LOGFILE >/dev/null 2>&1
424 if [ $? -ne 0 ]; then
425 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/z";
426 return 1
427 fi
428 let "count6 = count6 + 1" >/dev/null
429 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/${ff}/y" $LOGFILE >/dev/null 2>&1
430 if [ $? -ne 0 ]; then
431 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/y";
432 return 1
433 fi
434 let "count6 = count6 + 1" >/dev/null
435 done
436 tmp=`grep CRIT $LOGFILE | wc -l`
437 if [ $tmp -ne $count6 ]; then
438 [ -z "$verbose" ] || log_msg_fail "policy count";
439 return 1
440 fi
441}
442
443TESTPOLICY_5="
444[Attributes]
445dir=${BASE}
446file=${BASE}/a/a/c/x
447[ReadOnly]
448file=${BASE}/a/a/c/y
449[GrowingLogFiles]
450dir=${BASE}/a/a/c
451dir=${BASE}/a/a/b
452dir=${BASE}/a/b
453"
454
455mod_testdata_5 () {
456 mod_testdata_4
457 echo "This is a xxxx file" > "${BASE}/a/a/b/x" # GrowingLogFiles
458 echo "This is a test file" > "${BASE}/a/a/b/y" # GrowingLogFiles
459 echo "This is a xxxx file bad" > "${BASE}/a/a/b/z" # GrowingLogFiles
460}
461
462chk_testdata_5 () {
463 for ff in $TDIRS; do
464 #
465 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
466 if [ $? -ne 0 ]; then
467 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
468 return 1
469 fi
470 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
471 if [ $tmp -ne 1 ]; then
472 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
473 fi
474 #
475 for gg in $TFILES; do
476 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
477 if [ $? -ne 0 ]; then
478 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
479 fi
480 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
481 if [ $tmp -ne 1 ]; then
482 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
483 fi
484 done
485 done
486 egrep "CRIT.*POLICY \[GrowingLogs\] C---------.*${BASE}/a/a/b/x" $LOGFILE >/dev/null 2>&1
487 if [ $? -ne 0 ]; then
488 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/b/x";
489 return 1
490 fi
491 egrep "CRIT.*POLICY \[GrowingLogs\] C---------.*${BASE}/a/a/b/z" $LOGFILE >/dev/null 2>&1
492 if [ $? -ne 0 ]; then
493 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/b/z";
494 return 1
495 fi
496 egrep "CRIT.*POLICY \[GrowingLogs\] -----M----.*${BASE}/a/b/z" $LOGFILE >/dev/null 2>&1
497 if [ $? -ne 0 ]; then
498 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/z";
499 return 1
500 fi
501 egrep "CRIT.*POLICY \[GrowingLogs\] -----M----.*${BASE}/a/a/c/z" $LOGFILE >/dev/null 2>&1
502 if [ $? -ne 0 ]; then
503 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/z";
504 return 1
505 fi
506 egrep "CRIT.*POLICY \[GrowingLogs\] C--------S.*${BASE}/a/b/y" $LOGFILE >/dev/null 2>&1
507 if [ $? -ne 0 ]; then
508 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/y";
509 return 1
510 fi
511 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/a/c/x" $LOGFILE >/dev/null 2>&1
512 if [ $? -ne 0 ]; then
513 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/x";
514 return 1
515 fi
516 egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/c/foo" $LOGFILE >/dev/null 2>&1
517 if [ $? -ne 0 ]; then
518 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/foo";
519 return 1
520 fi
521 egrep "CRIT.*POLICY ADDED.*033\[1;30m" $LOGFILE >/dev/null 2>&1
522 if [ $? -ne 0 ]; then
523 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/\033[1;30m";
524 return 1
525 fi
526 egrep "WARN.*Weird filename.*033\[1;30m" $LOGFILE >/dev/null 2>&1
527 if [ $? -ne 0 ]; then
528 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/\033[1;30m";
529 return 1
530 fi
531 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/a/c/y" $LOGFILE >/dev/null 2>&1
532 if [ $? -ne 0 ]; then
533 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/y";
534 return 1
535 fi
536 tmp=`grep CRIT $LOGFILE | wc -l`
537 if [ $tmp -ne 9 ]; then
538 [ -z "$verbose" ] || log_msg_fail "policy count";
539 return 1
540 fi
541}
542
543
544TESTPOLICY_4="
545[Attributes]
546dir=${BASE}
547file=${BASE}/a/a/c/x
548[ReadOnly]
549file=${BASE}/a/a/c/y
550[LogFiles]
551dir=${BASE}/a/a/c
552dir=${BASE}/a/b
553"
554
555mod_testdata_4 () {
556 one_sec_sleep
557 echo "foobar" >> "${BASE}/a/a/x" # Attributes
558 echo "foobar" > "${BASE}/a/a/c/foo" # new within LogFiles
559 echo "foobar" >> "${BASE}/a/a/c/y" # ReadOnly
560 echo "foobar" >> "${BASE}/a/a/c/x" # Attributes
561 chmod 0555 "${BASE}/a/a/c/x" # Attributes
562 chmod 0555 "${BASE}/a/a/c/z" # LogFiles
563 echo "foobar" >> "${BASE}/a/b/x" # LogFiles
564 echo "" > "${BASE}/a/b/y" # LogFiles
565 chmod 0555 "${BASE}/a/b/z" # LogFiles
566 touch "${BASE}/a/a/[1;30m" # non-printable character in filename
567}
568
569chk_testdata_4 () {
570 for ff in $TDIRS; do
571 #
572 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
573 if [ $? -ne 0 ]; then
574 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
575 return 1
576 fi
577 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
578 if [ $tmp -ne 1 ]; then
579 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
580 fi
581 #
582 for gg in $TFILES; do
583 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
584 if [ $? -ne 0 ]; then
585 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
586 fi
587 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
588 if [ $tmp -ne 1 ]; then
589 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
590 fi
591 done
592 done
593 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/a/c/x" $LOGFILE >/dev/null 2>&1
594 if [ $? -ne 0 ]; then
595 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/x";
596 return 1
597 fi
598 egrep "CRIT.*POLICY \[LogFiles\] -----M----.*${BASE}/a/b/z" $LOGFILE >/dev/null 2>&1
599 if [ $? -ne 0 ]; then
600 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/z";
601 return 1
602 fi
603 egrep "CRIT.*POLICY \[LogFiles\] -----M----.*${BASE}/a/a/c/z" $LOGFILE >/dev/null 2>&1
604 if [ $? -ne 0 ]; then
605 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/z";
606 return 1
607 fi
608 egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/c/foo" $LOGFILE >/dev/null 2>&1
609 if [ $? -ne 0 ]; then
610 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/foo";
611 return 1
612 fi
613 egrep "CRIT.*POLICY ADDED.*033\[1;30m" $LOGFILE >/dev/null 2>&1
614 if [ $? -ne 0 ]; then
615 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/\033[1;30m";
616 return 1
617 fi
618 egrep "WARN.*Weird filename.*033\[1;30m" $LOGFILE >/dev/null 2>&1
619 if [ $? -ne 0 ]; then
620 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/\033[1;30m";
621 return 1
622 fi
623 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/a/c/y" $LOGFILE >/dev/null 2>&1
624 if [ $? -ne 0 ]; then
625 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/y";
626 return 1
627 fi
628 tmp=`grep CRIT $LOGFILE | wc -l`
629 if [ $tmp -ne 6 ]; then
630 [ -z "$verbose" ] || log_msg_fail "policy count";
631 return 1
632 fi
633}
634
635TESTPOLICY_3="
636[Attributes]
637dir=${BASE}
638file=${BASE}/a/a/c/x
639[ReadOnly]
640file=${BASE}/a/a/c/y
641[IgnoreAll]
642dir=${BASE}/a/a/c
643"
644mod_testdata_3 () {
645 one_sec_sleep
646 echo "foobar" > "${BASE}/a/b/foo" # new within Attributes
647 chmod 0555 "${BASE}/a/b"
648 echo "foobar" > "${BASE}/a/a/c/foo" # new within IgnoreAll
649 echo "foobar" > "${BASE}/a/a/c/y" # ReadOnly
650 chmod 0555 "${BASE}/a/a/c/x" # Attributes
651 chmod 0555 "${BASE}/a/a/c/z" # IgnoreAll
652}
653
654chk_testdata_3 () {
655 for ff in $TDIRS; do
656 #
657 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
658 if [ $? -ne 0 ]; then
659 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
660 return 1
661 fi
662 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
663 if [ $tmp -ne 1 ]; then
664 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
665 fi
666 #
667 for gg in $TFILES; do
668 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
669 if [ $? -ne 0 ]; then
670 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
671 fi
672 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
673 if [ $tmp -ne 1 ]; then
674 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
675 fi
676 done
677 done
678 egrep "CRIT.*POLICY ADDED.*${BASE}/a/b/foo" $LOGFILE >/dev/null 2>&1
679 if [ $? -ne 0 ]; then
680 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/foo";
681 return 1
682 fi
683 egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/c/foo" $LOGFILE >/dev/null 2>&1
684 if [ $? -ne 0 ]; then
685 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/foo";
686 return 1
687 fi
688 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/b" $LOGFILE >/dev/null 2>&1
689 if [ $? -ne 0 ]; then
690 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b";
691 return 1
692 fi
693 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/a/c/x" $LOGFILE >/dev/null 2>&1
694 if [ $? -ne 0 ]; then
695 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/x";
696 return 1
697 fi
698 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/a/c/y" $LOGFILE >/dev/null 2>&1
699 if [ $? -ne 0 ]; then
700 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/y";
701 return 1
702 fi
703 tmp=`grep CRIT $LOGFILE | wc -l`
704 if [ $tmp -ne 5 ]; then
705 [ -z "$verbose" ] || log_msg_fail "policy count";
706 return 1
707 fi
708}
709
710TESTPOLICY_2="
711[ReadOnly]
712dir=${BASE}
713file=${BASE}/a/a/c/x
714[IgnoreAll]
715dir=${BASE}/a/a/c
716"
717mod_testdata_2 () {
718 mod_testdata_1;
719 rm "${BASE}/a/a/c/y"
720 echo "foobar" > "${BASE}/a/a/c/foo"
721 chmod 0555 "${BASE}/a/a/c/x"
722 chmod 0555 "${BASE}/a/a/c/z"
723}
724
725chk_testdata_2 () {
726 for ff in $TDIRS; do
727 #
728 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
729 if [ $? -ne 0 ]; then
730 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
731 return 1
732 fi
733 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
734 if [ $tmp -ne 1 ]; then
735 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
736 fi
737 #
738 for gg in $TFILES; do
739 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
740 if [ $? -ne 0 ]; then
741 if [ x"${ff}/${gg}" = x"a/a/c/y" ]; then :; else
742 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
743 return 1
744 fi
745 fi
746 done
747 done
748 egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/c/foo" $LOGFILE >/dev/null 2>&1
749 if [ $? -ne 0 ]; then
750 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/foo";
751 return 1
752 fi
753 egrep "CRIT.*POLICY MISSING.*${BASE}/a/a/c/y" $LOGFILE >/dev/null 2>&1
754 if [ $? -ne 0 ]; then
755 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/y";
756 return 1
757 fi
758 egrep "CRIT.*POLICY \[ReadOnly\] -----M--T-.*${BASE}/a/a/c/x" $LOGFILE >/dev/null 2>&1
759 if [ $? -ne 0 ]; then
760 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/x";
761 return 1
762 fi
763 tmp=`grep CRIT $LOGFILE | wc -l`
764 if [ $tmp -ne 8 ]; then
765 [ -z "$verbose" ] || log_msg_fail "policy count";
766 return 1
767 fi
768}
769
770TESTPOLICY_1="
771[ReadOnly]
772dir=${BASE}
773"
774
775mod_testdata_1 () {
776 one_sec_sleep
777 touch "${BASE}/a/a/x"
778 chmod 0555 "${BASE}/a/a/y"
779 mv "${BASE}/a/b/y" "${BASE}/a/b/yy"; echo "This is a test file" > "${BASE}/a/b/y"; rm "${BASE}/a/b/yy"
780 echo "foobar" > "${BASE}/a/c/y"
781}
782
783chk_testdata_1 () {
784 for ff in $TDIRS; do
785 #
786 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
787 if [ $? -ne 0 ]; then
788 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
789 return 1
790 fi
791 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
792 if [ $tmp -ne 1 ]; then
793 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
794 fi
795 #
796 for gg in $TFILES; do
797 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
798 if [ $? -ne 0 ]; then
799 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
800 return 1
801 fi
802 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
803 if [ $tmp -ne 1 ]; then
804 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
805 fi
806 done
807 done
808 egrep "CRIT.*POLICY \[ReadOnly\] --------T-.*${BASE}/a/a/x" $LOGFILE >/dev/null 2>&1
809 if [ $? -ne 0 ]; then
810 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/x";
811 return 1
812 fi
813 egrep "CRIT.*POLICY \[ReadOnly\] -----M--T-.*${BASE}/a/a/y" $LOGFILE >/dev/null 2>&1
814 if [ $? -ne 0 ]; then
815 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y";
816 return 1
817 fi
818 egrep "CRIT.*POLICY \[ReadOnly\] ---I----T-.*${BASE}/a/b/y" $LOGFILE >/dev/null 2>&1
819 if [ $? -ne 0 ]; then
820 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/y";
821 return 1
822 fi
823 egrep "CRIT.*POLICY \[ReadOnly\] --------T-.*${BASE}/a/b" $LOGFILE >/dev/null 2>&1
824 if [ $? -ne 0 ]; then
825 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b";
826 return 1
827 fi
828 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/c/y" $LOGFILE >/dev/null 2>&1
829 if [ $? -ne 0 ]; then
830 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/c/y";
831 return 1
832 fi
833 tmp=`grep CRIT $LOGFILE | wc -l`
834 if [ $tmp -ne 5 ]; then
835 [ -z "$verbose" ] || log_msg_fail "policy count";
836 return 1
837 fi
838 return 0
839}
840
841
842##############################################################
843#
844# Common subroutines
845#
846
847mkconfig_misc ()
848{
849 test -f "${RCFILE}" || touch "${RCFILE}"
850 cat >> "${RCFILE}" <<End-of-data
851[Misc]
852Daemon=no
853SetFilecheckTime=60
854TrustedUser=uucp,fax,fnet
855SetRecursionLevel=10
856SetLoopTime=30
857ReportFullDetail = no
858ChecksumTest=check
859
860End-of-data
861}
862
863mkconfig_log ()
864{
865 test -f "${RCFILE}" || touch "${RCFILE}"
866 cat >> "${RCFILE}" <<End-of-data
867[Log]
868MailSeverity=none
869LogSeverity=warn
870SyslogSeverity=none
871PrintSeverity=info
872MailSeverity=none
873#Restrict to certain classes of messages
874#LogClass=RUN
875#PreludeSeverity=err
876#ExportSeverity=none
877
878End-of-data
879}
880
881mkconfig_sev ()
882{
883 test -f "${RCFILE}" || touch "${RCFILE}"
884 cat >> "${RCFILE}" <<End-of-data
885[EventSeverity]
886SeverityUser0=crit
887SeverityUser1=crit
888SeverityReadOnly=crit
889SeverityLogFiles=crit
890SeverityGrowingLogs=crit
891SeverityIgnoreNone=crit
892SeverityAttributes=crit
893SeverityIgnoreAll=crit
894SeverityFiles=err
895SeverityDirs=err
896SeverityNames=warn
897
898End-of-data
899}
900
901prep_testpolicy ()
902{
903 test -f "${RCFILE}" || touch "${RCFILE}"
904 eval echo '"$'"TESTPOLICY_$1"'"' >>"${RCFILE}"
905}
906
907prep_init ()
908{
909 rm -f ./.samhain_file
910 rm -f "${LOGFILE}"
911 rm -f ./.samhain_lock
912
913 rm -f "${RCFILE}"
914 mkconfig_sev
915 mkconfig_log
916 mkconfig_misc
917}
918
919run_init ()
920{
921 rm -f test_log_valgrind
922
923 ${VALGRIND} ./samhain -t init -p none 2>>test_log_valgrind
924
925 if test x$? = x0; then
926 [ -z "$verbose" ] || log_msg_ok "init...";
927 else
928 [ -z "$quiet" ] && log_msg_fail "init...";
929 return 1
930 fi
931}
932
933run_check ()
934{
935 ${VALGRIND} ./samhain -t check -p none -l debug 2>>test_log_valgrind
936
937 if test x$? = x0; then
938
939 ./samhain -j -L $LOGFILE >"${LOGFILE}.tmp" && mv "${LOGFILE}.tmp" "${LOGFILE}"
940
941 if [ $? -ne 0 ]; then
942 [ -z "$quiet" ] && log_msg_fail "mv logfile...";
943 return 1
944 fi
945 [ -z "$verbose" ] || log_msg_ok "check...";
946 else
947 [ -z "$quiet" ] && log_msg_fail "check...";
948 return 1
949 fi
950}
951
952run_update ()
953{
954 ${VALGRIND} ./samhain -t update -p none -l debug 2>>test_log_valgrind
955
956 if test x$? = x0; then
957 [ -z "$verbose" ] || log_msg_ok "update...";
958 else
959 [ -z "$quiet" ] && log_msg_fail "update...";
960 return 1
961 fi
962}
963
964run_check_after_update ()
965{
966 rm -rf $LOGFILE
967
968 ${VALGRIND} ./samhain -t check -p none -l debug 2>>test_log_valgrind
969
970 if test x$? = x0; then
971 #
972 tmp=`./samhain -j -L $LOGFILE | grep CRIT | wc -l`
973 if [ $tmp -ne 0 ]; then
974 [ -z "$verbose" ] || log_msg_fail "update not successful(?)";
975 return 1
976 fi
977 #
978 # wtmp may not be readable
979 #
980 tmp=`./samhain -j -L $LOGFILE | grep ERR | grep -v wtmp | wc -l`
981 if [ $tmp -ne 0 ]; then
982 [ -z "$verbose" ] || log_msg_fail "errors during check";
983 return 1
984 fi
985 #
986 [ -z "$VALGRIND" ] || {
987 tmp=`cat test_log_valgrind 2>/dev/null | wc -l`;
988 if [ $tmp -ne 0 ]; then
989 [ -z "$verbose" ] || log_msg_fail "valgrind reports errors";
990 cat test_log_valgrind
991 return 1;
992 fi;
993 }
994 #
995 [ -z "$verbose" ] || log_msg_ok "check(2)...";
996 else
997 [ -z "$quiet" ] && log_msg_fail "check(2)...";
998 return 1
999 fi
1000}
1001
1002prep_testdata ()
1003{
1004 if test -d "$BASE"; then
1005 if [ -d "${BASE}" ]; then
1006 chmod -R 0700 "${BASE}" || {
1007 [ -z "$quiet" ] && log_msg_fail "chmod -R 0700 ${BASE}";
1008 return 1;
1009 }
1010 fi
1011 fi
1012
1013 rm -rf "${BASE}" || {
1014 [ -z "$quiet" ] && log_msg_fail "rm -rf ${BASE}";
1015 return 1;
1016 }
1017
1018 mkdir "${BASE}" || {
1019 [ -z "$quiet" ] && log_msg_fail "mkdir ${BASE}";
1020 return 1;
1021 }
1022
1023 for ff in $TDIRS; do
1024 mkdir "${BASE}/${ff}" || {
1025 [ -z "$quiet" ] && log_msg_fail "mkdir ${BASE}/${ff}";
1026 return 1;
1027 }
1028 chmod 0755 "${BASE}/${ff}"
1029 for gg in $TFILES; do
1030 echo "This is a test file" > "${BASE}/${ff}/${gg}"
1031 chmod 0644 "${BASE}/${ff}/${gg}"
1032 done
1033 done
1034}
1035
1036check_err ()
1037{
1038 if [ $1 -ne 0 ]; then
1039 log_fail ${2} ${MAXTEST};
1040 return 1
1041 fi
1042 return 0
1043}
1044
1045testrun_internal ()
1046{
1047 [ -z "$verbose" ] || echo Working directory: $PW_DIR
1048 [ -z "$verbose" ] || { echo MAKE is $MAKE; echo; }
1049
1050 #
1051 # test standalone compilation
1052 #
1053 [ -z "$verbose" ] || { echo; echo "${S}Building standalone agent${E}"; echo; }
1054
1055 if test -r "Makefile"; then
1056 $MAKE distclean >/dev/null
1057 fi
1058
1059 ${TOP_SRCDIR}/configure ${BUILDOPTS}
1060
1061 #
1062 if test x$? = x0; then
1063 [ -z "$verbose" ] || log_msg_ok "configure...";
1064 $MAKE >/dev/null 2>>test_log
1065 if test x$? = x0; then
1066 [ -z "$verbose" ] || log_msg_ok "make...";
1067 else
1068 [ -z "$quiet" ] && log_msg_fail "make...";
1069 return 1
1070 fi
1071
1072 else
1073 [ -z "$quiet" ] && log_msg_fail "configure...";
1074 return 1
1075 fi
1076
1077 [ -z "$verbose" ] || { echo; echo "${S}Running test suite${E}"; echo; }
1078
1079 tcount=1
1080 POLICY=`eval echo '"$'"TESTPOLICY_$tcount"'"'`
1081
1082 until [ -z "$POLICY" ]
1083 do
1084 prep_init
1085 check_err $? ${tcount}; errval=$?
1086 if [ $errval -eq 0 ]; then
1087 prep_testdata
1088 check_err $? ${tcount}; errval=$?
1089 fi
1090 if [ $errval -eq 0 ]; then
1091 prep_testpolicy ${tcount}
1092 check_err $? ${tcount}; errval=$?
1093 fi
1094 if [ $errval -eq 0 ]; then
1095 run_init
1096 check_err $? ${tcount}; errval=$?
1097 fi
1098 if [ $errval -eq 0 ]; then
1099 eval mod_testdata_${tcount}
1100 check_err $? ${tcount}; errval=$?
1101 fi
1102 if [ $errval -eq 0 ]; then
1103 run_check
1104 check_err $? ${tcount}; errval=$?
1105 fi
1106 if [ $errval -eq 0 ]; then
1107 eval chk_testdata_${tcount}
1108 check_err $? ${tcount}; errval=$?
1109 fi
1110 if [ $testrun1_setup -eq 0 ]; then
1111 if [ $errval -eq 0 ]; then
1112 run_update
1113 check_err $? ${tcount}; errval=$?
1114 fi
1115 if [ $errval -eq 0 ]; then
1116 run_check_after_update
1117 check_err $? ${tcount}; errval=$?
1118 fi
1119 fi
1120 #
1121 if [ $errval -eq 0 ]; then
1122 [ -z "$quiet" ] && log_ok ${tcount} ${MAXTEST};
1123 fi
1124 #
1125 let "tcount = tcount + 1" >/dev/null
1126 #
1127 if [ -z "$doall" -a $tcount -eq 10 ]; then
1128 log_skip 10 $MAXTEST 'ACL/SELinux test (or use --really-all)'
1129 let "tcount = tcount + 1" >/dev/null
1130 fi
1131 #
1132 if [ -z "$doall" -a $tcount -eq 11 ]; then
1133 log_skip 11 $MAXTEST 'ACL/SELinux test (or use --really-all)'
1134 let "tcount = tcount + 1" >/dev/null
1135 fi
1136 #
1137 POLICY=`eval echo '"$'"TESTPOLICY_$tcount"'"'`
1138 done
1139
1140 return 0
1141}
1142
1143testrun1 ()
1144{
1145 log_start "RUN STANDALONE"
1146 testrun_internal
1147 log_end "RUN STANDALONE"
1148 return 0
1149}
1150
1151
1152
Note: See TracBrowser for help on using the repository browser.