Index: /trunk/src/cutest_sh_utils.c
===================================================================
--- /trunk/src/cutest_sh_utils.c	(revision 21)
+++ /trunk/src/cutest_sh_utils.c	(revision 21)
@@ -0,0 +1,46 @@
+
+#include "config_xor.h"
+
+#include <string.h>
+#include "CuTest.h"
+#include "samhain.h"
+#include "sh_utils.h"
+
+void Test_sh_util_obscure_ok (CuTest *tc) {
+
+  int ret = 0;
+  char input[16] = "foobar";
+#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
+
+  ret = sh_util_obscure_ok ("0xA1,0xA2,0xA3");
+  CuAssertIntEquals(tc, ret, 0);
+
+  ret = sh_util_obscurename (0, input, S_FALSE /* no log message */);
+  CuAssertIntEquals(tc, ret, 0);
+
+  input[0] = '\t';
+  ret = sh_util_obscurename (0, input, S_FALSE /* no log message */);
+  CuAssertIntEquals(tc, ret, -1);
+
+  input[0] = 0xA1;
+  ret = sh_util_obscurename (0, input, S_FALSE /* no log message */);
+  CuAssertIntEquals(tc, ret, 0);
+
+  input[0] = 0xA2;
+  ret = sh_util_obscurename (0, input, S_FALSE /* no log message */);
+  CuAssertIntEquals(tc, ret, 0);
+
+  input[0] = 0xA3;
+  ret = sh_util_obscurename (0, input, S_FALSE /* no log message */);
+  CuAssertIntEquals(tc, ret, 0);
+
+  input[0] = 0xA4;
+  ret = sh_util_obscurename (0, input, S_FALSE /* no log message */);
+  CuAssertIntEquals(tc, ret, -1);
+
+#else
+  CuAssertIntEquals(tc, ret, 0);
+#endif
+}
+
+
Index: /trunk/src/cutest_slib.c
===================================================================
--- /trunk/src/cutest_slib.c	(revision 21)
+++ /trunk/src/cutest_slib.c	(revision 21)
@@ -0,0 +1,26 @@
+
+#include "config_xor.h"
+
+#include <string.h>
+#include "CuTest.h"
+#include "samhain.h"
+
+void Test_sl_snprintf (CuTest *tc) {
+
+  int ret = 0;
+  char input[16];
+
+  memset (&input, 'X', 16);
+  ret = sl_snprintf(input, 10, "%s\n", "01234567890123456789");
+  CuAssertIntEquals(tc, ret, 0);
+  CuAssertTrue(tc, input[9]  == '\0');
+  CuAssertTrue(tc, input[10] == 'X');
+
+  memset (&input, 'X', 16);
+  ret = sl_snprintf(input, 4, "%d\n", "012345");
+  CuAssertIntEquals(tc, ret, 0);
+  CuAssertTrue(tc, input[3] == '\0');
+  CuAssertTrue(tc, input[4] == 'X');
+}
+
+
Index: /trunk/test/testrun_1c.sh
===================================================================
--- /trunk/test/testrun_1c.sh	(revision 21)
+++ /trunk/test/testrun_1c.sh	(revision 21)
@@ -0,0 +1,312 @@
+#! /bin/sh
+
+BUILDOPTS="--quiet $TRUST --enable-xml-log --enable-suidcheck --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"
+export BUILDOPTS
+
+MAXTEST=6; export MAXTEST
+
+## Quarantine SUID/SGID files if found
+#
+# SuidCheckQuarantineFiles = yes
+
+## Method for Quarantining files:
+#  0 - Delete or truncate the file.
+#  1 - Remove SUID/SGID permissions from file.
+#  2 - Move SUID/SGID file to quarantine dir.
+#
+# SuidCheckQuarantineMethod = 0
+
+## For method 0 and 2, really delete instead of truncating
+# 
+# SuidCheckQuarantineDelete = yes
+
+SUIDPOLICY_6="
+[ReadOnly]
+file=${BASE}
+[SuidCheck]
+SuidCheckActive = yes
+SuidCheckInterval = 10
+SeveritySuidCheck = crit
+SuidCheckQuarantineFiles = no
+SuidCheckQuarantineMethod = 2
+SuidCheckQuarantineDelete = yes
+"
+
+mod_suiddata_6 () {
+    sleep 1
+    chmod 4755 "${BASE}/a/a/y"
+}
+
+chk_suiddata_6 () {
+    sleep 1
+    tmp=`ls -l "${BASE}/a/a/y" 2>/dev/null | awk '{ print $1}'`
+    if [ "x$tmp" = "x-rwsr-xr-x" ]; then
+	egrep "CRIT.*POLICY \[SuidCheck\].*${BASE}/a/a/y" $LOGFILE >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y";
+	    return 1
+	fi
+	egrep "CRIT.*POLICY ADDED.*${BASE}/a/a/y" $LOGFILE >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y";
+	    return 1
+	fi
+	return 0;
+    else
+	[ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y (suid not kept)";
+	return 1
+    fi
+}
+
+SUIDPOLICY_5="
+[ReadOnly]
+file=${BASE}
+[SuidCheck]
+SuidCheckActive = yes
+SuidCheckInterval = 10
+SeveritySuidCheck = crit
+SuidCheckQuarantineFiles = yes
+SuidCheckQuarantineMethod = 2
+SuidCheckQuarantineDelete = yes
+"
+
+mod_suiddata_5 () {
+    sleep 1
+    chmod 4755 "${BASE}/a/a/y"
+}
+
+chk_suiddata_5 () {
+    sleep 1
+    if [ -f "${BASE}/a/a/y" ]; then
+	[ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y (not deleted)";
+	return 1
+    fi
+    if [ -f .quarantine/y ]; then
+	if [ -f .quarantine/y.info ]; then
+	    return 0;
+	else
+	    [ -z "$verbose" ] || log_msg_fail ".quarantine/y.info (missing)";
+	    return 1
+	fi
+    else
+	[ -z "$verbose" ] || log_msg_fail ".quarantine/y (missing)";
+	return 1
+    fi
+}
+
+SUIDPOLICY_4="
+[ReadOnly]
+file=${BASE}
+[SuidCheck]
+SuidCheckActive = yes
+SuidCheckInterval = 10
+SeveritySuidCheck = crit
+SuidCheckQuarantineFiles = yes
+SuidCheckQuarantineMethod = 2
+SuidCheckQuarantineDelete = no
+"
+
+mod_suiddata_4 () {
+    sleep 1
+    chmod 4755 "${BASE}/a/a/y"
+}
+
+chk_suiddata_4 () {
+    sleep 1
+    tmp=`cat "${BASE}/a/a/y" 2>/dev/null | wc -c`
+    if [ $tmp -ne 0 ]; then
+	[ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y (not truncated)";
+	return 1
+    fi
+    if [ -f .quarantine/y ]; then
+	if [ -f .quarantine/y.info ]; then
+	    return 0;
+	else
+	    [ -z "$verbose" ] || log_msg_fail ".quarantine/y.info (missing)";
+	    return 1
+	fi
+    else
+	[ -z "$verbose" ] || log_msg_fail ".quarantine/y (missing)";
+	return 1
+    fi
+}
+
+SUIDPOLICY_3="
+[ReadOnly]
+file=${BASE}
+[SuidCheck]
+SuidCheckActive = yes
+SuidCheckInterval = 10
+SeveritySuidCheck = crit
+SuidCheckQuarantineFiles = yes
+SuidCheckQuarantineMethod = 1
+SuidCheckQuarantineDelete = no
+"
+
+mod_suiddata_3 () {
+    sleep 1
+    chmod 4755 "${BASE}/a/a/y"
+}
+
+chk_suiddata_3 () {
+    sleep 1
+    tmp=`ls -l "${BASE}/a/a/y" 2>/dev/null | awk '{ print $1}'`
+    if [ "x$tmp" = "x-rwxr-xr-x" ]; then
+	return 0;
+    else
+	[ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y (suid not removed)";
+	return 1
+    fi
+}
+
+SUIDPOLICY_2="
+[ReadOnly]
+file=${BASE}
+[SuidCheck]
+SuidCheckActive = yes
+SuidCheckInterval = 10
+SeveritySuidCheck = crit
+SuidCheckQuarantineFiles = yes
+SuidCheckQuarantineMethod = 0
+SuidCheckQuarantineDelete = no
+"
+
+mod_suiddata_2 () {
+    sleep 1
+    chmod 4755 "${BASE}/a/a/y"
+}
+
+chk_suiddata_2 () {
+    sleep 1
+    tmp=`cat "${BASE}/a/a/y" 2>/dev/null | wc -c`
+    if [ $tmp -ne 0 ]; then
+	[ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y (not truncated)";
+	return 1
+    fi
+}
+
+SUIDPOLICY_1="
+[ReadOnly]
+file=${BASE}
+[SuidCheck]
+SuidCheckActive = yes
+SuidCheckInterval = 10
+SeveritySuidCheck = crit
+SuidCheckQuarantineFiles = yes
+SuidCheckQuarantineMethod = 0
+SuidCheckQuarantineDelete = yes
+"
+
+mod_suiddata_1 () {
+    sleep 1
+    chmod 4755 "${BASE}/a/a/y"
+}
+
+chk_suiddata_1 () {
+    sleep 1
+    if [ -f "${BASE}/a/a/y" ]; then
+	[ -z "$verbose" ] || log_msg_fail "${BASE}/a/a/y (not removed)";
+	return 1
+    fi
+}
+
+prep_suidpolicy ()
+{
+    test -f "${RCFILE}" || touch "${RCFILE}"
+    eval echo '"$'"SUIDPOLICY_$1"'"' >>"${RCFILE}"
+}
+
+testrun_internal_1c ()
+{
+	[ -z "$verbose" ] || echo Working directory: $PW_DIR
+	[ -z "$verbose" ] || { echo MAKE is $MAKE; echo; }
+
+	#
+	# test standalone compilation
+	#
+	[ -z "$verbose" ] || { echo; echo "${S}Building standalone agent${E}"; echo; }
+
+	if test -r "Makefile"; then
+		$MAKE distclean >/dev/null 
+	fi
+
+	${TOP_SRCDIR}/configure ${BUILDOPTS} 
+
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE  'DBGDEF=-DSH_SUIDTESTDIR=\"${BASE}\"' >/dev/null
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	[ -z "$verbose" ] || { echo; echo "${S}Running test suite${E}"; echo; }
+
+	tcount=1
+	POLICY=`eval echo '"$'"SUIDPOLICY_$tcount"'"'`
+
+	until [ -z "$POLICY" ]
+	do
+	  prep_init
+	  check_err $? ${tcount}; errval=$?
+	  if [ $errval -eq 0 ]; then
+	      prep_testdata
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      prep_suidpolicy   ${tcount}
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      run_init
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      eval mod_suiddata_${tcount}
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      run_check
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      eval chk_suiddata_${tcount}
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $testrun1_setup -eq 0 ]; then
+	      if [ $errval -eq 0 ]; then
+		  run_update
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	      if [ $errval -eq 0 ]; then
+		  run_check_after_update
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	  fi
+	  #
+	  if [ $errval -eq 0 ]; then
+	      [ -z "$quiet" ] && log_ok ${tcount} ${MAXTEST};
+	  fi
+	  let "tcount = tcount + 1" >/dev/null
+	  POLICY=`eval echo '"$'"SUIDPOLICY_$tcount"'"'`
+	done
+	    
+	return 0
+}
+
+testrun1c ()
+{
+    log_start "RUN STANDALONE W/SUIDCHK"
+    testrun_internal_1c
+    log_end "RUN STANDALONE W/SUIDCHK"
+    return 0
+}
+
