source: trunk/test/testrun_1.sh@ 97

Last change on this file since 97 was 68, checked in by rainer, 18 years ago

Update trunk to samhain 2.3

File size: 29.5 KB
RevLine 
[1]1#! /bin/sh
2
[27]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
[19]22RCFILE="$PW_DIR/testrc_1.dyn"; export RCFILE
23LOGFILE="$PW_DIR/.samhain_log"; export LOGFILE
[1]24
[19]25# --enable-login-watch --enable-xml-log
26# --enable-debug --enable-suidcheck --with-prelude
[1]27
[19]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
[1]30
[19]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
[1]34
[19]35###########################################################
36#
37# ---- [Define tests here] ----
38#
[1]39
[19]40# 1 for testing new tests
41testrun1_setup=0
42
[68]43MAXTEST=13; export MAXTEST
[19]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
[1]52 fi
[19]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
[25]69#
70# combine file check schedule with one-shot mode
71#
[68]72TESTPOLICY_13="
[25]73[ReadOnly]
74dir=99${BASE}
75"
76
[68]77mod_testdata_13 () {
[51]78 one_sec_sleep
[25]79 echo "foobar" >"${BASE}/c/x"; # bad
80 chmod 0555 "${BASE}/a/y"; # bad
81 ORIGINAL='SetFilecheckTime=60'
82 REPLACEMENT='FileCheckScheduleOne = 6 12 * * *'
[51]83 ex -s $RCFILE <<EOF
[30]84%s/${ORIGINAL}/${REPLACEMENT}/g
85wq
[25]86EOF
87}
88
[68]89chk_testdata_13 () {
[25]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
[68]112TESTPOLICY_12="
[19]113[ReadOnly]
114dir=99${BASE}
115[IgnoreAll]
116dir=-1${BASE}/b
117[Attributes]
118dir=1${BASE}/a
119"
120
[68]121mod_testdata_12 () {
[51]122 one_sec_sleep
[19]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
[68]131chk_testdata_12 () {
[19]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
[1]137 fi
[19]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}
[1]158
[68]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
[19]251TESTPOLICY_9="
252[ReadOnly]
253dir=0${BASE}/b
254[Attributes]
255dir=2${BASE}/a/a
256"
[1]257
[19]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"
314
315mod_testdata_7 () {
[51]316 one_sec_sleep
[19]317 echo "foobar" >"${BASE}/a/a/a/z" # ok
318 echo "foobar" >"${BASE}/a/a/a/x" # bad
319 echo "foobar" >"${BASE}/a/a/x" # ok
320 echo "foobar" >"${BASE}/a/x" # bad
321 chmod 0555 "${BASE}/a" # bad
322 chmod 0555 "${BASE}/b" # ok
323}
324
325
326chk_testdata_7 () {
327 tmp=`grep CRIT $LOGFILE | wc -l`
328 if [ $tmp -ne 3 ]; then
329 [ -z "$verbose" ] || log_msg_fail "policy count";
330 return 1
331 fi
332 egrep "CRIT.*POLICY \[GrowingLogs\] C--------S.*${BASE}/a/a/a/x" $LOGFILE >/dev/null 2>&1
333 if [ $? -ne 0 ]; then
334 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/a/x";
335 return 1
336 fi
337 egrep "CRIT.*POLICY \[ReadOnly\] -----M--T-.*${BASE}/a" $LOGFILE >/dev/null 2>&1
338 if [ $? -ne 0 ]; then
339 [ -z "$verbose" ] || log_msg_fail "${BASE}/a";
340 return 1
341 fi
342 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/x" $LOGFILE >/dev/null 2>&1
343 if [ $? -ne 0 ]; then
344 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/x";
345 return 1
346 fi
347}
348
349
350TESTPOLICY_6="
351[ReadOnly]
352dir=${BASE}
353[Attributes]
354file=${BASE}/a/y
355file=${BASE}/b/y
356file=${BASE}/c/y
357file=${BASE}/a/a/y
358file=${BASE}/a/b/y
359file=${BASE}/a/c/y
360file=${BASE}/a/a/a/y
361file=${BASE}/a/a/b/y
362file=${BASE}/a/a/c/y
363file=${BASE}/a/a/a/a/y
364file=${BASE}/a/a/a/b/y
365file=${BASE}/a/a/a/c/y
366"
367
368mod_testdata_6 () {
[51]369 one_sec_sleep
[19]370 for ff in $TDIRS; do
371 echo "foobar" >"${BASE}/${ff}/x"
372 chmod 0555 "${BASE}/${ff}/y"
373 echo "foobar" >"${BASE}/${ff}/z"
374 done
375}
376
377chk_testdata_6 () {
378 count6=0
379 for ff in $TDIRS; do
[1]380 #
[19]381 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
382 if [ $? -ne 0 ]; then
383 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
384 return 1
385 fi
386 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
387 if [ $tmp -ne 1 ]; then
388 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
389 fi
[1]390 #
[19]391 for gg in $TFILES; do
392 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
393 if [ $? -ne 0 ]; then
394 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
395 fi
396 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
397 if [ $tmp -ne 1 ]; then
398 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
399 fi
400 done
401 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/${ff}/x" $LOGFILE >/dev/null 2>&1
402 if [ $? -ne 0 ]; then
403 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/x";
404 return 1
405 fi
406 let "count6 = count6 + 1" >/dev/null
407 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/${ff}/z" $LOGFILE >/dev/null 2>&1
408 if [ $? -ne 0 ]; then
409 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/z";
410 return 1
411 fi
412 let "count6 = count6 + 1" >/dev/null
413 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/${ff}/y" $LOGFILE >/dev/null 2>&1
414 if [ $? -ne 0 ]; then
415 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/y";
416 return 1
417 fi
418 let "count6 = count6 + 1" >/dev/null
419 done
420 tmp=`grep CRIT $LOGFILE | wc -l`
421 if [ $tmp -ne $count6 ]; then
422 [ -z "$verbose" ] || log_msg_fail "policy count";
423 return 1
424 fi
425}
426
427TESTPOLICY_5="
428[Attributes]
429dir=${BASE}
430file=${BASE}/a/a/c/x
431[ReadOnly]
432file=${BASE}/a/a/c/y
433[GrowingLogFiles]
434dir=${BASE}/a/a/c
435dir=${BASE}/a/a/b
436dir=${BASE}/a/b
437"
438
439mod_testdata_5 () {
440 mod_testdata_4
441 echo "This is a xxxx file" > "${BASE}/a/a/b/x" # GrowingLogFiles
442 echo "This is a test file" > "${BASE}/a/a/b/y" # GrowingLogFiles
443 echo "This is a xxxx file bad" > "${BASE}/a/a/b/z" # GrowingLogFiles
444}
445
446chk_testdata_5 () {
447 for ff in $TDIRS; do
[1]448 #
[19]449 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
450 if [ $? -ne 0 ]; then
451 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
452 return 1
[1]453 fi
[19]454 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
455 if [ $tmp -ne 1 ]; then
456 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
457 fi
[1]458 #
[19]459 for gg in $TFILES; do
460 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
461 if [ $? -ne 0 ]; then
462 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
463 fi
464 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
465 if [ $tmp -ne 1 ]; then
466 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
467 fi
468 done
469 done
470 egrep "CRIT.*POLICY \[GrowingLogs\] C---------.*${BASE}/a/a/b/x" $LOGFILE >/dev/null 2>&1
471 if [ $? -ne 0 ]; then
472 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/b/x";
473 return 1
474 fi
475 egrep "CRIT.*POLICY \[GrowingLogs\] C---------.*${BASE}/a/a/b/z" $LOGFILE >/dev/null 2>&1
476 if [ $? -ne 0 ]; then
477 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/b/z";
478 return 1
479 fi
480 egrep "CRIT.*POLICY \[GrowingLogs\] -----M----.*${BASE}/a/b/z" $LOGFILE >/dev/null 2>&1
481 if [ $? -ne 0 ]; then
482 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/z";
483 return 1
484 fi
485 egrep "CRIT.*POLICY \[GrowingLogs\] -----M----.*${BASE}/a/a/c/z" $LOGFILE >/dev/null 2>&1
486 if [ $? -ne 0 ]; then
487 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/z";
488 return 1
489 fi
490 egrep "CRIT.*POLICY \[GrowingLogs\] C--------S.*${BASE}/a/b/y" $LOGFILE >/dev/null 2>&1
491 if [ $? -ne 0 ]; then
492 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/y";
493 return 1
494 fi
495 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/a/c/x" $LOGFILE >/dev/null 2>&1
496 if [ $? -ne 0 ]; then
497 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/x";
498 return 1
499 fi
500 egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/c/foo" $LOGFILE >/dev/null 2>&1
501 if [ $? -ne 0 ]; then
502 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/foo";
503 return 1
504 fi
505 egrep "CRIT.*POLICY ADDED.*033\[1;30m" $LOGFILE >/dev/null 2>&1
506 if [ $? -ne 0 ]; then
507 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/\033[1;30m";
508 return 1
509 fi
510 egrep "WARN.*Weird filename.*033\[1;30m" $LOGFILE >/dev/null 2>&1
511 if [ $? -ne 0 ]; then
512 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/\033[1;30m";
513 return 1
514 fi
515 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/a/c/y" $LOGFILE >/dev/null 2>&1
516 if [ $? -ne 0 ]; then
517 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/y";
518 return 1
519 fi
520 tmp=`grep CRIT $LOGFILE | wc -l`
521 if [ $tmp -ne 9 ]; then
522 [ -z "$verbose" ] || log_msg_fail "policy count";
523 return 1
524 fi
525}
[1]526
527
[19]528TESTPOLICY_4="
529[Attributes]
530dir=${BASE}
531file=${BASE}/a/a/c/x
532[ReadOnly]
533file=${BASE}/a/a/c/y
534[LogFiles]
535dir=${BASE}/a/a/c
536dir=${BASE}/a/b
537"
[1]538
[19]539mod_testdata_4 () {
[51]540 one_sec_sleep
[19]541 echo "foobar" >> "${BASE}/a/a/x" # Attributes
542 echo "foobar" > "${BASE}/a/a/c/foo" # new within LogFiles
543 echo "foobar" >> "${BASE}/a/a/c/y" # ReadOnly
544 echo "foobar" >> "${BASE}/a/a/c/x" # Attributes
545 chmod 0555 "${BASE}/a/a/c/x" # Attributes
546 chmod 0555 "${BASE}/a/a/c/z" # LogFiles
547 echo "foobar" >> "${BASE}/a/b/x" # LogFiles
548 echo "" > "${BASE}/a/b/y" # LogFiles
549 chmod 0555 "${BASE}/a/b/z" # LogFiles
550 touch "${BASE}/a/a/[1;30m" # non-printable character in filename
551}
[1]552
[19]553chk_testdata_4 () {
554 for ff in $TDIRS; do
555 #
556 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
557 if [ $? -ne 0 ]; then
558 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
559 return 1
560 fi
561 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
562 if [ $tmp -ne 1 ]; then
563 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
564 fi
565 #
566 for gg in $TFILES; do
567 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
568 if [ $? -ne 0 ]; then
569 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
570 fi
571 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
572 if [ $tmp -ne 1 ]; then
573 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
574 fi
575 done
576 done
577 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/a/c/x" $LOGFILE >/dev/null 2>&1
578 if [ $? -ne 0 ]; then
579 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/x";
580 return 1
581 fi
582 egrep "CRIT.*POLICY \[LogFiles\] -----M----.*${BASE}/a/b/z" $LOGFILE >/dev/null 2>&1
583 if [ $? -ne 0 ]; then
584 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/z";
585 return 1
586 fi
587 egrep "CRIT.*POLICY \[LogFiles\] -----M----.*${BASE}/a/a/c/z" $LOGFILE >/dev/null 2>&1
588 if [ $? -ne 0 ]; then
589 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/z";
590 return 1
591 fi
592 egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/c/foo" $LOGFILE >/dev/null 2>&1
593 if [ $? -ne 0 ]; then
594 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/foo";
595 return 1
596 fi
597 egrep "CRIT.*POLICY ADDED.*033\[1;30m" $LOGFILE >/dev/null 2>&1
598 if [ $? -ne 0 ]; then
599 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/\033[1;30m";
600 return 1
601 fi
602 egrep "WARN.*Weird filename.*033\[1;30m" $LOGFILE >/dev/null 2>&1
603 if [ $? -ne 0 ]; then
604 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/\033[1;30m";
605 return 1
606 fi
607 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/a/c/y" $LOGFILE >/dev/null 2>&1
608 if [ $? -ne 0 ]; then
609 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/y";
610 return 1
611 fi
612 tmp=`grep CRIT $LOGFILE | wc -l`
613 if [ $tmp -ne 6 ]; then
614 [ -z "$verbose" ] || log_msg_fail "policy count";
615 return 1
616 fi
617}
[1]618
[19]619TESTPOLICY_3="
620[Attributes]
621dir=${BASE}
622file=${BASE}/a/a/c/x
623[ReadOnly]
624file=${BASE}/a/a/c/y
625[IgnoreAll]
626dir=${BASE}/a/a/c
627"
628mod_testdata_3 () {
[51]629 one_sec_sleep
[19]630 echo "foobar" > "${BASE}/a/b/foo" # new within Attributes
631 chmod 0555 "${BASE}/a/b"
632 echo "foobar" > "${BASE}/a/a/c/foo" # new within IgnoreAll
633 echo "foobar" > "${BASE}/a/a/c/y" # ReadOnly
634 chmod 0555 "${BASE}/a/a/c/x" # Attributes
635 chmod 0555 "${BASE}/a/a/c/z" # IgnoreAll
636}
[1]637
[19]638chk_testdata_3 () {
639 for ff in $TDIRS; do
[1]640 #
[19]641 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
642 if [ $? -ne 0 ]; then
643 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
644 return 1
645 fi
646 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
647 if [ $tmp -ne 1 ]; then
648 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
649 fi
650 #
651 for gg in $TFILES; do
652 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
653 if [ $? -ne 0 ]; then
654 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
655 fi
656 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
657 if [ $tmp -ne 1 ]; then
658 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
659 fi
660 done
661 done
662 egrep "CRIT.*POLICY ADDED.*${BASE}/a/b/foo" $LOGFILE >/dev/null 2>&1
663 if [ $? -ne 0 ]; then
664 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/foo";
665 return 1
666 fi
667 egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/c/foo" $LOGFILE >/dev/null 2>&1
668 if [ $? -ne 0 ]; then
669 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/foo";
670 return 1
671 fi
672 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/b" $LOGFILE >/dev/null 2>&1
673 if [ $? -ne 0 ]; then
674 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b";
675 return 1
676 fi
677 egrep "CRIT.*POLICY \[Attributes\] -----M----.*${BASE}/a/a/c/x" $LOGFILE >/dev/null 2>&1
678 if [ $? -ne 0 ]; then
679 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/x";
680 return 1
681 fi
682 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/a/c/y" $LOGFILE >/dev/null 2>&1
683 if [ $? -ne 0 ]; then
684 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/y";
685 return 1
686 fi
687 tmp=`grep CRIT $LOGFILE | wc -l`
688 if [ $tmp -ne 5 ]; then
689 [ -z "$verbose" ] || log_msg_fail "policy count";
690 return 1
691 fi
692}
693
694TESTPOLICY_2="
695[ReadOnly]
696dir=${BASE}
697file=${BASE}/a/a/c/x
698[IgnoreAll]
699dir=${BASE}/a/a/c
700"
701mod_testdata_2 () {
702 mod_testdata_1;
703 rm "${BASE}/a/a/c/y"
704 echo "foobar" > "${BASE}/a/a/c/foo"
705 chmod 0555 "${BASE}/a/a/c/x"
706 chmod 0555 "${BASE}/a/a/c/z"
707}
708
709chk_testdata_2 () {
710 for ff in $TDIRS; do
711 #
712 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
713 if [ $? -ne 0 ]; then
714 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
715 return 1
716 fi
717 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
718 if [ $tmp -ne 1 ]; then
719 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
720 fi
721 #
722 for gg in $TFILES; do
723 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
724 if [ $? -ne 0 ]; then
725 if [ x"${ff}/${gg}" = x"a/a/c/y" ]; then :; else
726 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
727 return 1
[1]728 fi
[19]729 fi
730 done
731 done
732 egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/c/foo" $LOGFILE >/dev/null 2>&1
733 if [ $? -ne 0 ]; then
734 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/foo";
735 return 1
736 fi
737 egrep "CRIT.*POLICY MISSING.*${BASE}/a/a/c/y" $LOGFILE >/dev/null 2>&1
738 if [ $? -ne 0 ]; then
739 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/y";
740 return 1
741 fi
742 egrep "CRIT.*POLICY \[ReadOnly\] -----M--T-.*${BASE}/a/a/c/x" $LOGFILE >/dev/null 2>&1
743 if [ $? -ne 0 ]; then
744 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/c/x";
745 return 1
746 fi
747 tmp=`grep CRIT $LOGFILE | wc -l`
748 if [ $tmp -ne 8 ]; then
749 [ -z "$verbose" ] || log_msg_fail "policy count";
750 return 1
751 fi
752}
[1]753
[19]754TESTPOLICY_1="
755[ReadOnly]
756dir=${BASE}
757"
758
759mod_testdata_1 () {
[51]760 one_sec_sleep
[19]761 touch "${BASE}/a/a/x"
762 chmod 0555 "${BASE}/a/a/y"
763 mv "${BASE}/a/b/y" "${BASE}/a/b/yy"; echo "This is a test file" > "${BASE}/a/b/y"; rm "${BASE}/a/b/yy"
764 echo "foobar" > "${BASE}/a/c/y"
765}
766
767chk_testdata_1 () {
768 for ff in $TDIRS; do
769 #
770 egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE >/dev/null 2>&1
771 if [ $? -ne 0 ]; then
772 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (checking)";
773 return 1
[1]774 fi
[19]775 tmp=`egrep "Checking.*${BASE}/${ff}(>|\")" $LOGFILE 2>/dev/null | wc -l`
776 if [ $tmp -ne 1 ]; then
777 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff} (multiple)";
778 fi
779 #
780 for gg in $TFILES; do
781 egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE >/dev/null 2>&1
782 if [ $? -ne 0 ]; then
783 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (checking)";
784 return 1
785 fi
786 tmp=`egrep "Checksum.*${BASE}/${ff}/${gg}" $LOGFILE 2>/dev/null | wc -l`
787 if [ $tmp -ne 1 ]; then
788 [ -z "$verbose" ] || log_msg_fail "${BASE}/${ff}/${gg} (multiple)";
789 fi
790 done
791 done
792 egrep "CRIT.*POLICY \[ReadOnly\] --------T-.*${BASE}/a/a/x" $LOGFILE >/dev/null 2>&1
793 if [ $? -ne 0 ]; then
794 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/x";
795 return 1
796 fi
797 egrep "CRIT.*POLICY \[ReadOnly\] -----M--T-.*${BASE}/a/a/y" $LOGFILE >/dev/null 2>&1
798 if [ $? -ne 0 ]; then
799 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y";
800 return 1
801 fi
802 egrep "CRIT.*POLICY \[ReadOnly\] ---I----T-.*${BASE}/a/b/y" $LOGFILE >/dev/null 2>&1
803 if [ $? -ne 0 ]; then
804 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b/y";
805 return 1
806 fi
807 egrep "CRIT.*POLICY \[ReadOnly\] --------T-.*${BASE}/a/b" $LOGFILE >/dev/null 2>&1
808 if [ $? -ne 0 ]; then
809 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/b";
810 return 1
811 fi
812 egrep "CRIT.*POLICY \[ReadOnly\] C-------TS.*${BASE}/a/c/y" $LOGFILE >/dev/null 2>&1
813 if [ $? -ne 0 ]; then
814 [ -z "$verbose" ] || log_msg_fail "${BASE}/a/c/y";
815 return 1
816 fi
817 tmp=`grep CRIT $LOGFILE | wc -l`
818 if [ $tmp -ne 5 ]; then
819 [ -z "$verbose" ] || log_msg_fail "policy count";
820 return 1
821 fi
822 return 0
823}
[1]824
825
[19]826##############################################################
827#
828# Common subroutines
829#
[1]830
[19]831mkconfig_misc ()
832{
833 test -f "${RCFILE}" || touch "${RCFILE}"
834 cat >> "${RCFILE}" <<End-of-data
835[Misc]
836Daemon=no
837SetFilecheckTime=60
838TrustedUser=uucp,fax,fnet
839SetRecursionLevel=10
840SetLoopTime=30
841ReportFullDetail = no
842ChecksumTest=check
843
844End-of-data
845}
846
847mkconfig_log ()
848{
849 test -f "${RCFILE}" || touch "${RCFILE}"
850 cat >> "${RCFILE}" <<End-of-data
851[Log]
852MailSeverity=none
853LogSeverity=warn
854SyslogSeverity=none
855PrintSeverity=info
856MailSeverity=none
857#Restrict to certain classes of messages
858#LogClass=RUN
859#PreludeSeverity=err
860#ExportSeverity=none
861
862End-of-data
863}
864
865mkconfig_sev ()
866{
867 test -f "${RCFILE}" || touch "${RCFILE}"
868 cat >> "${RCFILE}" <<End-of-data
869[EventSeverity]
870SeverityUser0=crit
871SeverityUser1=crit
872SeverityReadOnly=crit
873SeverityLogFiles=crit
874SeverityGrowingLogs=crit
875SeverityIgnoreNone=crit
876SeverityAttributes=crit
877SeverityIgnoreAll=crit
878SeverityFiles=err
879SeverityDirs=err
880SeverityNames=warn
881
882End-of-data
883}
884
885prep_testpolicy ()
886{
887 test -f "${RCFILE}" || touch "${RCFILE}"
888 eval echo '"$'"TESTPOLICY_$1"'"' >>"${RCFILE}"
889}
890
891prep_init ()
892{
893 rm -f ./.samhain_file
894 rm -f "${LOGFILE}"
895 rm -f ./.samhain_lock
896
897 rm -f "${RCFILE}"
898 mkconfig_sev
899 mkconfig_log
900 mkconfig_misc
901}
902
903run_init ()
904{
[22]905 rm -f test_log_valgrind
[19]906
[22]907 ${VALGRIND} ./samhain -t init -p none 2>>test_log_valgrind
908
[19]909 if test x$? = x0; then
910 [ -z "$verbose" ] || log_msg_ok "init...";
911 else
912 [ -z "$quiet" ] && log_msg_fail "init...";
913 return 1
914 fi
915}
916
917run_check ()
918{
[68]919 ${VALGRIND} ./samhain -t check -p none -l debug 2>>test_log_valgrind
920
921 if test x$? = x0; then
[19]922
923 ./samhain -j -L $LOGFILE >"${LOGFILE}.tmp" && mv "${LOGFILE}.tmp" "${LOGFILE}"
[68]924
[19]925 if [ $? -ne 0 ]; then
926 [ -z "$quiet" ] && log_msg_fail "mv logfile...";
927 return 1
928 fi
929 [ -z "$verbose" ] || log_msg_ok "check...";
930 else
931 [ -z "$quiet" ] && log_msg_fail "check...";
932 return 1
933 fi
934}
935
936run_update ()
937{
[22]938 ${VALGRIND} ./samhain -t update -p none -l debug 2>>test_log_valgrind
[19]939
940 if test x$? = x0; then
941 [ -z "$verbose" ] || log_msg_ok "update...";
942 else
943 [ -z "$quiet" ] && log_msg_fail "update...";
944 return 1
945 fi
946}
947
948run_check_after_update ()
949{
950 rm -rf $LOGFILE
951
[22]952 ${VALGRIND} ./samhain -t check -p none -l debug 2>>test_log_valgrind
[19]953
954 if test x$? = x0; then
955 #
956 tmp=`./samhain -j -L $LOGFILE | grep CRIT | wc -l`
957 if [ $tmp -ne 0 ]; then
958 [ -z "$verbose" ] || log_msg_fail "update not successful(?)";
959 return 1
960 fi
[30]961 #
962 # wtmp may not be readable
963 #
964 tmp=`./samhain -j -L $LOGFILE | grep ERR | grep -v wtmp | wc -l`
[19]965 if [ $tmp -ne 0 ]; then
[30]966 [ -z "$verbose" ] || log_msg_fail "errors during check";
[19]967 return 1
968 fi
969 #
[22]970 [ -z "$VALGRIND" ] || {
971 tmp=`cat test_log_valgrind 2>/dev/null | wc -l`;
972 if [ $tmp -ne 0 ]; then
973 [ -z "$verbose" ] || log_msg_fail "valgrind reports errors";
974 cat test_log_valgrind
975 return 1;
976 fi;
977 }
978 #
[19]979 [ -z "$verbose" ] || log_msg_ok "check(2)...";
980 else
981 [ -z "$quiet" ] && log_msg_fail "check(2)...";
982 return 1
983 fi
984}
985
986prep_testdata ()
987{
[30]988 if test -d "$BASE"; then
989 if [ -d "${BASE}" ]; then
990 chmod -R 0700 "${BASE}" || {
991 [ -z "$quiet" ] && log_msg_fail "chmod -R 0700 ${BASE}";
992 return 1;
993 }
994 fi
[22]995 fi
[19]996
997 rm -rf "${BASE}" || {
998 [ -z "$quiet" ] && log_msg_fail "rm -rf ${BASE}";
999 return 1;
1000 }
1001
1002 mkdir "${BASE}" || {
1003 [ -z "$quiet" ] && log_msg_fail "mkdir ${BASE}";
1004 return 1;
1005 }
1006
1007 for ff in $TDIRS; do
1008 mkdir "${BASE}/${ff}" || {
1009 [ -z "$quiet" ] && log_msg_fail "mkdir ${BASE}/${ff}";
1010 return 1;
1011 }
1012 chmod 0755 "${BASE}/${ff}"
1013 for gg in $TFILES; do
1014 echo "This is a test file" > "${BASE}/${ff}/${gg}"
1015 chmod 0644 "${BASE}/${ff}/${gg}"
1016 done
1017 done
1018}
1019
1020check_err ()
1021{
1022 if [ $1 -ne 0 ]; then
[68]1023 log_fail ${2} ${MAXTEST};
[19]1024 return 1
1025 fi
1026 return 0
1027}
1028
1029testrun_internal ()
1030{
1031 [ -z "$verbose" ] || echo Working directory: $PW_DIR
1032 [ -z "$verbose" ] || { echo MAKE is $MAKE; echo; }
1033
1034 #
1035 # test standalone compilation
1036 #
1037 [ -z "$verbose" ] || { echo; echo "${S}Building standalone agent${E}"; echo; }
1038
1039 if test -r "Makefile"; then
1040 $MAKE distclean >/dev/null
1041 fi
1042
1043 ${TOP_SRCDIR}/configure ${BUILDOPTS}
1044
1045 #
[1]1046 if test x$? = x0; then
[19]1047 [ -z "$verbose" ] || log_msg_ok "configure...";
[30]1048 $MAKE >/dev/null 2>>test_log
[1]1049 if test x$? = x0; then
[19]1050 [ -z "$verbose" ] || log_msg_ok "make...";
[1]1051 else
[19]1052 [ -z "$quiet" ] && log_msg_fail "make...";
1053 return 1
[1]1054 fi
[19]1055
[1]1056 else
[19]1057 [ -z "$quiet" ] && log_msg_fail "configure...";
1058 return 1
[1]1059 fi
1060
[19]1061 [ -z "$verbose" ] || { echo; echo "${S}Running test suite${E}"; echo; }
[1]1062
[19]1063 tcount=1
1064 POLICY=`eval echo '"$'"TESTPOLICY_$tcount"'"'`
[1]1065
[19]1066 until [ -z "$POLICY" ]
1067 do
1068 prep_init
1069 check_err $? ${tcount}; errval=$?
1070 if [ $errval -eq 0 ]; then
1071 prep_testdata
1072 check_err $? ${tcount}; errval=$?
1073 fi
1074 if [ $errval -eq 0 ]; then
1075 prep_testpolicy ${tcount}
1076 check_err $? ${tcount}; errval=$?
1077 fi
1078 if [ $errval -eq 0 ]; then
1079 run_init
1080 check_err $? ${tcount}; errval=$?
1081 fi
1082 if [ $errval -eq 0 ]; then
1083 eval mod_testdata_${tcount}
1084 check_err $? ${tcount}; errval=$?
1085 fi
1086 if [ $errval -eq 0 ]; then
1087 run_check
1088 check_err $? ${tcount}; errval=$?
1089 fi
1090 if [ $errval -eq 0 ]; then
1091 eval chk_testdata_${tcount}
1092 check_err $? ${tcount}; errval=$?
1093 fi
1094 if [ $testrun1_setup -eq 0 ]; then
1095 if [ $errval -eq 0 ]; then
1096 run_update
1097 check_err $? ${tcount}; errval=$?
1098 fi
1099 if [ $errval -eq 0 ]; then
1100 run_check_after_update
1101 check_err $? ${tcount}; errval=$?
1102 fi
1103 fi
1104 #
1105 if [ $errval -eq 0 ]; then
1106 [ -z "$quiet" ] && log_ok ${tcount} ${MAXTEST};
1107 fi
[68]1108 #
[19]1109 let "tcount = tcount + 1" >/dev/null
[68]1110 #
1111 if [ -z "$doall" -a $tcount -eq 10 ]; then
1112 log_skip 10 $MAXTEST 'ACL/SELinux test (or use --really-all)'
1113 let "tcount = tcount + 1" >/dev/null
1114 fi
1115 #
1116 if [ -z "$doall" -a $tcount -eq 11 ]; then
1117 log_skip 11 $MAXTEST 'ACL/SELinux test (or use --really-all)'
1118 let "tcount = tcount + 1" >/dev/null
1119 fi
1120 #
[19]1121 POLICY=`eval echo '"$'"TESTPOLICY_$tcount"'"'`
1122 done
1123
1124 return 0
1125}
[1]1126
[19]1127testrun1 ()
1128{
1129 log_start "RUN STANDALONE"
1130 testrun_internal
1131 log_end "RUN STANDALONE"
1132 return 0
1133}
[1]1134
1135
1136
Note: See TracBrowser for help on using the repository browser.