Index: trunk/scripts/README
===================================================================
--- trunk/scripts/README	(revision 584)
+++ trunk/scripts/README	(revision 1)
@@ -1,5 +1,5 @@
 
 
-This directory contains miscellaneous useful scripts, some of them contributed
+This directory contains miscellaneous useful scripts, mostly contributed
 by various users. Additions and/or improvements are welcome. 
 
@@ -28,14 +28,19 @@
    and database files.
 
-   Run 'samhainadmin.pl -h' for usage instructions.
+   Run 'samhainadmin.pl -h' for usage instaructions.
 
-yuleadmin.pl
-------------
+samhainrc_update.sh
+-------------------
 
-   Perl script (by Riccardo Murri) to list, add, and remove clients 
-   from the yulerc file.
+   If you are using the --with-kcheck option on Linux, after a kernel
+   update you need to change some option (addresses of kernel functions)
+   in the samhainrc configuration file. The correct new addresses must
+   be looked up in the System.map file
 
-   Run 'yuleadmin.pl -h' for usage instructions.
-
+   This script will do this automatically. Run 'samhainrc_update.sh -h'
+   for usage instructions. You may need to change the location of the
+   samhainrc file by editing the line 'SAMHAIN_CFG="/etc/samhainrc"'
+   at the beginning of the script.
+ 
 check_samhain.pl
 ----------------
@@ -97,3 +102,24 @@
 
 
+samhain-scripts/   Administrative scripts by 
+----------------   Simon Bailey <simon.bailey@uibk.ac.at> and
+                   Michael Redinger <michael.redinger@uibk.ac.at>
+
+		   You may need to adjust some of the variables in the
+		   top lines of these scripts.
+                
+   samhain.table.rotate.pl: Move old entries from mysql log table to a
+   			    backup table
+
+   samhain-admin: Interactive script to (1) clear log entries in SQL database,
+   		  (2) re-initialize file database of remote client, or (3) add
+		  a new host.
+		  This script requires that you are using samhains deploy
+		  system (i.e. the deploy.sh script et al.).
+		  Re-initialize will stop the daemon on the remote host,
+		  create a temp dir for the database, run samhain -t init,
+		  copy the database to the server, and clear the mysql log for
+		  this host.
+		  
+   samhain.clearhost: Helper script for samhain-admin.
 		   
Index: trunk/scripts/check_samhain.pl.in
===================================================================
--- trunk/scripts/check_samhain.pl.in	(revision 584)
+++ trunk/scripts/check_samhain.pl.in	(revision 1)
@@ -4,5 +4,5 @@
 #   by the samhain file integrity checker.
 #
-# Copyright Rainer Wichmann (2004, 2012)
+# Copyright Rainer Wichmann (2004)
 #
 # License Information:
@@ -28,5 +28,5 @@
 use Getopt::Long;
 use vars qw($PROGNAME $SAMHAIN $opt_V $opt_h $opt_v $verbose $opt_w $opt_c $opt_t $status $msg $state $retval);
-use lib  "/usr/local/nagios/libexec" ;
+use lib  utils.pm;
 use utils qw(%ERRORS &print_revision);
 
@@ -49,5 +49,5 @@
 # -----------------------------------------------------------------[ Global ]--
 
-$PROGNAME = "check_@install_name@";
+$PROGNAME = "check_samhain";
 $SAMHAIN = "@sbindir@/@install_name@"; 
 
@@ -99,5 +99,5 @@
     $state = $ERRORS{'WARNING'};
 } else {
-    $msg = "CRITICAL: $status policy violations (threshold c=$opt_c)";
+    $msg = "CRITICAL: $status policy violations (threshold w=$opt_w)";
     $state = $ERRORS{'CRITICAL'};
 }
@@ -143,5 +143,5 @@
     
     if ($opt_V) {
-	print_revision($PROGNAME,'$Revision: 1.1 $ ');
+	print_revision($PROGNAME,'$Revision: 1.0 $ ');
 	exit $ERRORS{'OK'};
     }
@@ -182,6 +182,6 @@
 
 sub print_help () {
-    print_revision($PROGNAME, '1.1');
-    print "Copyright (c) 2004,2012 Rainer Wichmann
+    print_revision($PROGNAME, '$Revision: 1.0 $');
+    print "Copyright (c) 2004 Rainer Wichmann
 
 This plugin checks the number of policy violations reported by the
Index: trunk/scripts/logrotate.in
===================================================================
--- trunk/scripts/logrotate.in	(revision 584)
+++ 	(revision )
@@ -1,24 +1,0 @@
-@mylogfile@ {
-    weekly
-    rotate 52
-    nocreate
-    missingok
-    compress
-
-    prerotate
-        if test -f @mylockfile@; then \
-          PIN=`cat @mylockfile@`; \
-          /bin/kill -TTIN $PIN; \
-          sleep 1; \
-          AA=0; \
-          while test "x$AA" != "x120"; do \
-           AA=$(( AA + 1 )); \
-           if test -f @mylogfile@.lock; then \
-             sleep 1; \
-           else \
-             break; \
-           fi \
-          done; \
-        fi
-    endscript
-}
Index: trunk/scripts/makeself/makeself.sh
===================================================================
--- trunk/scripts/makeself/makeself.sh	(revision 584)
+++ trunk/scripts/makeself/makeself.sh	(revision 1)
@@ -293,6 +293,5 @@
 echo Adding files to archive named \"$archname\"...
 (cd "$archdir"; tar $TAR_ARGS - * | eval "$GZIP_CMD" ) >> "$tmpfile" || { echo Aborting; rm -f "$tmpfile"; exit 1; }
-# The following command seems both superfluous and causing an 'I/O error' message
-# echo >> "$tmpfile" >&- # try to close the archive
+echo >> "$tmpfile" >&- # try to close the archive
 
 fsize=`cat "$tmpfile" | wc -c | tr -d " "`
Index: trunk/scripts/redhat_i386.client.spec.in
===================================================================
--- trunk/scripts/redhat_i386.client.spec.in	(revision 584)
+++ trunk/scripts/redhat_i386.client.spec.in	(revision 1)
@@ -78,6 +78,6 @@
 # after the package is installed
 install -m 700 samhain-install.sh init/samhain.startLinux init/samhain.startLSB ${RPM_BUILD_ROOT}/etc
-install -m 640 -o 0 -g 0 samhain_kmem.ko	${RPM_BUILD_ROOT}/lib/modules/`uname -r`/samhain_kmem.ko
-install -m 640 -o 0 -g 0 samhain_hide.ko        ${RPM_BUILD_ROOT}/lib/modules/`uname -r`/samhain_hide.ko
+install -m 640 -o 0 -g 0 samhain_hide.o		${RPM_BUILD_ROOT}/lib/modules/`uname -r`/samhain_hide.o
+install -m 640 -o 0 -g 0 samhain_erase.o	${RPM_BUILD_ROOT}/lib/modules/`uname -r`/samhain_erase.o
 install -m 700 -o 0 -g 0 samhain_setpwd		${RPM_BUILD_ROOT}/usr/local/sbin/samhain_setpwd
 
@@ -123,4 +123,10 @@
 fi
 
+%postun
+if [ "$1" = 0 ]; then
+        # remove any kernel modules that might have been installed
+        RVER=`uname -r`
+        rm -f /lib/modules/$RVER/samhain*
+fi
 
 
@@ -129,11 +135,10 @@
 %dir /var/run
 %dir /var/log
-#%doc docs/BUGS COPYING docs/Changelog 
-#%doc LICENSE docs/HOWTO* docs/MANUAL-2_4.* docs/README*
+#%doc docs/BUGS COPYING docs/Changelog docs/TODO
+#%doc LICENSE docs/HOWTO* docs/MANUAL-2_0.* docs/README*
 /etc
 /usr/local/sbin/samhain
 /usr/local/sbin/samhain_setpwd
 /lib/modules
-%attr(644,root,root) /etc/logrotate.d/@install_name@
 #%attr(644,root,root) /usr/local/man/man5/samhain*
 #%attr(644,root,root) /usr/local/man/man8/samhain*
Index: trunk/scripts/report.pl
===================================================================
--- trunk/scripts/report.pl	(revision 1)
+++ trunk/scripts/report.pl	(revision 1)
@@ -0,0 +1,239 @@
+#! /usr/bin/perl
+
+
+#
+
+# This tool will help extract the XML log file produced by Samhain
+# Put it into a more readable format that can then be run by CRON
+# and e-mailed to a user.
+#
+# Created: Ben <ben@deephouse.co.za>
+#
+#
+# Updates:
+# JUL 05 ver 1.1: - Updata to add in checkpint subroutine, this checks 
+#                   the scalar length
+#                   that is return from the log file if is is a good size
+#                   the program gets the value, if not value is returned it will not print it
+#                   to the report.
+#
+# JUL 07 ver 1.2: - Update to the Code to handle reporting selection 
+#                   from the command line.
+#                   Users are able to pass in [ReadOnly][LogFiles][Attributes].
+#                   Better support for date
+#
+# Version: 1.2
+
+
+
+
+
+use strict;
+
+use XML::Simple;
+
+use Tie::File;
+
+use POSIX qw(strftime);
+
+my $date=strftime("%a %b %d %H:%M:%S %Y", localtime());
+
+my $tdate = `date +'%m%d%y'`;   # Just to time stamp the files
+
+my $hostname = `hostname`; chomp($hostname);
+
+my $policy = $ARGV[1];
+
+
+
+&main();
+
+
+
+sub main {
+
+
+
+       unless (@ARGV == 2) { printf("Usage: $0 Samhain_report.xml <policyname. ReadOnly> \n"); exit(0); }
+
+        printf("## Reporting Starting\n");
+
+        &eatfile();
+
+        &extractdata($policy);
+
+        printf("## Report completed\n");
+
+        printf("## Your new report file has been created : Samhain-report-$hostname.$tdate\n");
+
+}
+
+
+
+# This routine will pull the data from the XML file, and sort through it
+
+# and look for the policy for [ReadOnly], once it has bfound that it will detected all the changes
+
+# within the policy
+
+#
+
+sub extractdata {
+
+   my $xmlfile = $ARGV[0];
+
+   my $config = XMLin($xmlfile);
+
+   # Create new report file
+
+   open(RP, ">fmre_report-$hostname.$tdate") || die ("Unable to open new report file, $!\n");
+
+    printf RP ("Samhain CRITICAL REPORT FOR $hostname\n");
+
+    printf RP ("\n");
+
+    printf RP ("This report was created on : $date\n");
+
+    printf RP ("Samhain Reporting Tool version 1.0\n");
+
+    printf RP ("Created: Ben Cuthbert <benjamin.cuthbert\@db.com>\n");
+
+    printf RP ("\n");
+
+    printf RP ("Report for !! $_[0] Policy !!\n");
+
+    printf RP ("\n");
+
+    # STart getting all of the data from xml file
+
+   foreach my $alert (@{$config->{'LOG'}}) {
+
+         if($alert->{msg} =~ /POLICY \[$_[0]]/) {       # Check we are on the correct policy
+
+          print RP ("File Changed: $alert->{path}\n");
+
+          &checkprint("$alert->{mtime_new}","Time Changed Old:   $alert->{mtime_new}");
+
+          &checkprint("$alert->{mtime_new}","Time Changed New:   $alert->{mtime_old}");
+
+          &checkprint("$alert->{mode_old}","Mode Old:   $alert->{mode_old}");
+
+          &checkprint("$alert->{mode_new}","Mode New:   $alert->{mode_new}");
+
+          &checkprint("$alert->{chksum_old}","CheckSum Old:     $alert->{chksum_old}");
+
+          &checkprint("$alert->{chksum_new}","CheckSum New:     $alert->{chksum_new}");
+
+          &checkprint("$alert->{size_new}","Size New:     $alert->{size_new}");
+
+          &checkprint("$alert->{size_old}","Size Old:     $alert->{size_old}");
+
+          printf RP ("\n");
+
+         }
+
+   }
+
+   printf RP ("Created Using: Samhain XML Reporting tool.\n");
+
+   printf RP ("Created By: Ben Cuthbert ben\@deephouse.co.za.\n");
+
+   close(RP);
+
+}
+
+
+
+# This helps with logs that do not have Entires for Certain modes ie --rwx
+
+# Get the scalar back, check the lenght then print out if the lenght is
+
+# bigger than 1
+
+sub checkprint {
+
+        chomp;
+
+        my $l = length($_[0]);
+
+        if($l gt 1) {
+
+                printf RP ("$_[1]\n");
+
+        }
+
+}
+
+# We need to change the structure of the HRML file from FMRE
+
+# so that we have the following tree structure.
+
+#VAR1 = {
+
+#        'LOG' => [
+
+#                  {
+
+#                       'msg' = 'value'
+
+#
+
+# The reason for this is it makes extraction better.
+
+#
+
+# So we open XML file and enter the following details.
+
+# <config> please at top of file
+
+# </config> place at bottom of file
+
+# </trail><trail> remove trails, as we do not require them as
+
+# log files are rotated every day.
+
+# reports will only run on the day.
+
+sub eatfile {
+
+        # Search and reaplce log with LOG, makes it easy
+
+        open(FH, "$ARGV[0]") || die ("Unable to ammend file \n");
+
+        open(FW, ">tmp.xml") || die ("Unable to ammend file \n");
+
+        while (<FH>) {
+
+         $_ =~ s/^---*//g; $_ =~ s/log/LOG/g; $_ =~ s/<trail>//g; $_ =~ s/<\/trail>//g; $_ =~ s/Log file printed//g;
+
+         printf FW $_;
+
+        }
+
+        close(FW); close(FH); system("mv tmp.xml $ARGV[0]");
+
+        # Put in <config> & </config> at top and bottom
+
+        open(FH, ">>$ARGV[0]") || die ("Unable to ammend file \n");
+
+        seek FH,0,2;
+
+        printf FH "</config>";
+
+        close(FH);
+
+        ## Star the insert at the top and bottom, close the config </config>
+
+        tie(my @FH1, 'Tie::File', $ARGV[0]) or die("Unable to read file, $!\n");
+
+        unshift @FH1, '<config>';
+
+        untie @FH1;
+
+        printf ("Xml file has been modified to run with this program \n");
+
+}
+
+
+
+
Index: trunk/scripts/samhain-scripts/samhain-admin
===================================================================
--- trunk/scripts/samhain-scripts/samhain-admin	(revision 1)
+++ trunk/scripts/samhain-scripts/samhain-admin	(revision 1)
@@ -0,0 +1,398 @@
+#!/bin/sh
+
+YULERC="/etc/yulerc"
+YULEDIR="/var/lib/yule"
+YULELOG="/var/log/yule/yule_log"
+YULEUSER="yule"
+YULEGROUP="yule"
+YULERESTART="/sbin/service yule restart"
+
+deploybin="/usr/local/sbin/deploy.sh"
+
+# this is used for creating hosts only
+# (to check if this is a valid host)
+# if you uncomment it, this check will not be performed
+FORCEDOMAIN="yourdomain.net"
+
+action_dbclear="/usr/local/sbin/samhain.clearhost"
+
+
+geth() {
+	unset HLIST
+	unset FQHLIST
+	
+	for file in $(ls ${YULEDIR}/file* | egrep -v ".bak$" | egrep -v ".log$" | \
+		egrep -v ".mgmt$" | egrep -v ".old$" | egrep -v ".sav$" ) ;  do
+		# strip path
+		fn=$(basename ${file})
+		# strip leading "file."
+		fqhn=${fn#file.}
+		# strip trailing domain
+		hn=${fqhn%%.*}
+		# write results to two arrays
+		FQHLIST[${#FQHLIST[*]}]=$fqhn
+		HLIST[${#HLIST[*]}]=$hn
+	done
+	
+	# get the length of the two arrays
+	hlistlen=${#HLIST[*]}
+	fqhlistlen=${#FQHLIST[*]}
+
+	# run until a valid selection is made
+	while [ 1 ] ; do
+		clear
+		echo "HOST LIST SELECTION"
+		echo
+		
+		# loop through array, print echo each host
+		arrpos=0
+		while [ ${arrpos} -lt ${hlistlen} ] ; do
+			echo -e "$((${arrpos}+1)).\t${HLIST[${arrpos}]}"
+			arrpos=$((${arrpos}+1))
+		done
+		
+		echo
+		echo -n "Please select a host (q to quit): "
+		 
+		read hostsel
+		
+		if [ "${hostsel}" = "q" ] ; then
+			exit
+		fi
+
+		isnum=$(echo ${hostsel} | egrep "^[[:digit:]]*$")
+		if [ "${isnum}" ] ; then
+			if [ ${hostsel} -gt 0 -a ${hostsel} -lt $((${hlistlen}+1)) ]
+			then
+				hostsel=$((${hostsel}-1))
+				break
+			fi
+		fi
+	done
+}
+
+
+getprof() {
+	unset PLIST
+	for entry in $(find ${YULEDIR}/profiles -type d -maxdepth 1) ; do
+		entry=$(basename ${entry})
+		if [ ! "${entry}" = "src" -a ! "${entry}" = "profiles" ] ; then
+			PLIST[${#PLIST[*]}]=${entry}
+		fi
+	done
+	
+	# array length
+	plistlen=${#PLIST[*]}
+}
+
+
+
+
+cleardb() {
+# clear the SQL database
+	geth
+	(
+		echo "Clearing database for ${HLIST[${hostsel}]}:"
+		${action_dbclear} ${HLIST[${hostsel}]} 2>&1 && \
+			echo "exit 0"
+	) | less
+} 
+
+
+
+# re-init part
+rrinit() {
+
+	geth
+
+	if [ ! -f ${YULEDIR}/file.${FQHLIST[${hostsel}]} ] ;  then
+		echo "File ${YULEDIR}/file.${FQHLIST[${hostsel}]} does not exist. Exiting."
+		exit 42
+	fi
+
+	if [ ! -f ${YULEDIR}/rc.${FQHLIST[${hostsel}]} ] ;  then
+		echo "File ${YULEDIR}/rc.${FQHLIST[${hostsel}]} does not exist. Exiting."
+		exit 42
+	fi
+
+	echo "Please see the yule log if you really want to reinit the samhain database."
+	echo "This is a really ugly XML file. Better get out of here ..."
+	echo -n "Press ENTER to continue. "
+	read forgetthisone
+
+
+	while [ 1 ] ; do
+		grep "remote_host=\"${HLIST[${hostsel}]}\"" ${YULELOG} | less
+	
+		echo -n "Now that you've seen this: do you still want to continue? (y) (q to quit): "
+		read goforit
+
+		if [ "${goforit}" = "q" ] ; then
+			exit
+		fi
+
+		if [ "${goforit}" = "y" ] ; then
+			break
+		fi
+	done
+
+
+	# Clean the database
+	echo "Clearing database for ${HLIST[${hostsel}]}:"
+	${action_dbclear} ${HLIST[${hostsel}]} 2>&1 && echo "exit 0"
+
+
+	# now run remotely
+	# this code is _really_ funny ... :)
+	ssh -x root@${FQHLIST[${hostsel}]} \
+	'if [ ! -d /samhain-deploy ] ; then \
+	        mkdir /samhain-deploy ; \
+	fi ; \
+	if [ -f /samhain-deploy/sh_database ] ; then \
+		rm -f /samhain-deploy/sh_database ; \
+	fi ; \
+	if [ -x /usr/bin/monit -a "$(/usr/bin/monit status | grep samhain)" ] ; then \
+	        monit stop samhain && sleep 5 ; \
+	elif [ -x /etc/init.d/samhain ] ; then \
+	        /etc/init.d/samhain stop ; \
+	elif [ -x /etc/rc.d/init.d/samhain ] ; then \
+	        /etc/rc.d/init.d/samhain stop ;
+	else \
+		kill $(cat /var/run/samhain.pid) ; \
+	fi ; \
+	/sbin/samhain -t init '
+	echo -n -e '\a' ; sleep 1
+	echo -n -e '\a' ; sleep 1
+	echo -n -e '\a' ; sleep 1
+	echo -n -e '\a' ; sleep 1
+	echo -n -e '\a'
+
+	# backup old database
+	cp ${YULEDIR}/file.${FQHLIST[${hostsel}]} ${YULEDIR}/file.${FQHLIST[${hostsel}]}.mgmt
+
+	# get the new database
+	scp root@${FQHLIST[${hostsel}]}:/samhain-deploy/sh_database \
+		${YULEDIR}/file.${FQHLIST[${hostsel}]} && \
+	chown  ${YULEUSER}:${YULEGROUP} ${YULEDIR}/file.${FQHLIST[${hostsel}]} && \
+	chmod 600 ${YULEDIR}/file.${FQHLIST[${hostsel}]}
+	echo -n -e '\a' ; sleep 1
+	echo -n -e '\a' ; sleep 1
+	echo -n -e '\a' ; sleep 1
+	echo -n -e '\a' ; sleep 1
+	echo -n -e '\a'
+
+	while [ 1 ] ; do
+		echo
+		echo -n "Do you want to start the remote samhain client now? (y/n/q) "
+		read remotestart
+		
+		if [ "${remotestart}" = "q" ] ; then
+			exit
+		fi		
+
+		if [ "${remotestart}" = "y" -o "${remotestart}" = "n" ] ; then
+			break
+		fi
+	done
+
+	if [ "${remotestart}" = "y" ] ; then
+		# restart samhain on remote host
+		ssh -x root@${FQHLIST[${hostsel}]} \
+	        'if [ -f /samhain-deploy/sh_database ] ; then \
+	                rm -f /samhain-deploy/sh_database ; \
+	        fi ; \
+		if [ -x /usr/bin/monit -a "$(/usr/bin/monit status | grep samhain)" ] ; then \
+	        monit start samhain ; \
+		elif [ -x /etc/init.d/samhain ] ; then \
+		        /etc/init.d/samhain start ; \
+		elif [ -x /etc/rc.d/init.d/samhain ] ; then \
+		        /etc/rc.d/init.d/samhain start ;
+		else \
+		        echo "Do not know how to start samhain." ; \
+		fi'
+		echo -n -e '\a' ; sleep 1
+		echo -n -e '\a' ; sleep 1
+		echo -n -e '\a' ; sleep 1
+       		echo -n -e '\a' ; sleep 1
+		echo -n -e '\a'
+		
+		echo "done"
+	fi
+}
+
+
+# add a new host
+addnewhost() {
+	getprof
+
+	while [ 1 ] ; do
+	        clear
+	        echo "PROFILE SELECTION"
+	        echo
+	        
+	        # loop through array, print echo each host
+	        arrpos=0
+	        while [ ${arrpos} -lt ${plistlen} ] ; do
+	                echo -e "$((${arrpos}+1)).\t${PLIST[${arrpos}]}"
+	                arrpos=$((${arrpos}+1))
+	        done
+	        
+	        echo
+	        echo -n "Please select a profile (q to quit): "
+	
+	        read psel
+	
+	        if [ "${psel}" = "p" ] ; then
+	                exit
+	        fi
+	
+		if [ ${psel} -gt 0 -a ${psel} -lt $((${plistlen}+1)) ] ; then
+                	psel=$((${psel}-1))
+                	break
+		fi
+	done
+
+	while [ 1 ] ; do
+		echo
+		echo -n "Enter a fully qualified host name: "
+		read newhost
+		foundpoint=$(echo ${newhost} | egrep "\.")
+		if [ "${foundpoint}" ] ; then
+			break
+		else
+			echo "Dude, a FQHN please!"
+			continue
+		fi
+		if [ "${FORCEDOMAIN}" ] ; then
+			if [ "$(echo ${newhost} | egrep \"\.${FORCEDOMAIN}$\")" ] ; then
+				break
+			else
+				echo "Host must be in domain ${FORCEDOMAIN}"
+				continue
+			fi
+		fi
+	done
+
+
+	while [ 1 ] ; do
+		echo "You are going to run the following command:"
+		echo "${deploybin} --remote-host=${newhost} --build-OS=${PLIST[${psel}]} --clients=${YULERC}"
+		echo -n "Continue? (y/n/q) "
+		read pconf
+
+		if [ "${pconf}" = "q" ] ; then
+			exit
+		fi
+
+		if [ "${pconf}" = "y" -o "${pconf}" = "n" ] ; then
+			break
+		fi
+	done
+
+	if [ ${pconf} = "y" ] ; then
+		${deploybin} --remote-host=${newhost} --build-OS=${PLIST[${psel}]} --clients=${YULERC}
+
+
+		chown ${YULEUSER}:${YULEGROUP} ${YULEDIR}/file.${newhost} ${YULEDIR}/rc.${newhost}
+
+		while [ 1 ] ; do
+			echo
+			echo "Yule has to be restarted before the client is started."
+			echo -n "Do you want to restart yule now? (y|n) "
+			read yulerestart
+	
+			if [ "${yulerestart}" = "y" -o "${yulerestart}" = "n" ] ; then
+				break
+			fi
+		done
+	
+		if [ "${yulerestart}" = "y" ] ; then
+			eval ${YULERESTART}
+		fi
+
+
+		while [ 1 ] ; do
+			echo
+			echo -n "Do you want to start the remote samhain client now? (y|n) "
+			read startsam
+			if [ "${startsam}" = "y" -o "${startsam}" = "n" ] ; then
+	                        break
+	                fi
+		done
+
+
+		if [ "${startsam}" = "y" ] ; then
+
+			echo "x${newhost}x"
+
+			ssh -x root@${newhost} \
+			'if [ -f /var/run/samhain.pid ] ; then \
+				if [ -x /usr/bin/monit -a "$(/usr/bin/monit status | grep samhain)" ] ; then \
+					monit stop samhain && sleep 5 ; \
+				elif [ -x /etc/init.d/samhain ] ; then \
+					/etc/init.d/samhain stop ; \
+				elif [ -x /etc/rc.d/init.d/samhain ] ; then \
+					/etc/rc.d/init.d/samhain stop ;
+				else \
+					kill $(cat /var/run/samhain.pid) ; \
+				fi ; \
+			fi ; \
+			if [ -x /usr/bin/monit -a "$(/usr/bin/monit status | grep samhain)" ] ; then \
+				monit start samhain ; \
+			elif [ -x /etc/init.d/samhain ] ; then \
+				/etc/init.d/samhain start ; \
+			elif [ -x /etc/rc.d/init.d/samhain ] ; then \
+				/etc/rc.d/init.d/samhain start ;
+			else \
+				echo "Do not know how to start samhain." ; \
+			fi'
+	                echo -n -e '\a' ; sleep 1
+	                echo -n -e '\a' ; sleep 1
+	                echo -n -e '\a' ; sleep 1
+	                echo -n -e '\a' ; sleep 1
+	                echo -n -e '\a'
+	        fi
+	fi
+
+
+}
+
+
+
+
+# run until a valid selection is made
+while [ 1 ] ; do
+	clear
+	
+	echo "SELECT ACTION"
+	echo
+	
+	echo -e "1.\tOnly clear log entries in SQL database"
+	echo -e "2.\tReinitialize host database"
+	echo -e "3.\tAdd a new host"
+	echo
+	echo -n "Select an action (q to quit): "
+	
+	read action
+	
+	if [ "${action}" = "q" ] ; then
+                exit
+        fi
+
+	if [ "${action}" = "1" ] ; then
+		cleardb
+	fi
+
+	if [ "${action}" = "2" ] ; then
+		rrinit
+	fi
+
+	if [ "${action}" = "3" ] ; then
+		addnewhost
+	fi
+
+done
+
+
+
+
Index: trunk/scripts/samhain-scripts/samhain.clearhost
===================================================================
--- trunk/scripts/samhain-scripts/samhain.clearhost	(revision 1)
+++ trunk/scripts/samhain-scripts/samhain.clearhost	(revision 1)
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+[[ ${#} = 1 ]] || exit 42
+
+SAMHAIN_DB='samhain'
+SAMHAIN_SRV='localhost'
+SAMHAIN_PRT='3306'
+SAMHAIN_USR='samhain'
+SAMHAIN_PWD='*******'
+
+
+mysql -u ${SAMHAIN_USR} --password=${SAMHAIN_PWD} ${SAMHAIN_DB} \
+	-P ${SAMHAIN_PRT} -h ${SAMHAIN_SRV} \
+	-e 'select count(*) from log where log_host="'${1}'";'  || \
+( echo "SELECT FAILED" && exit 42 )
+
+mysql -u ${SAMHAIN_USR} --password=${SAMHAIN_PWD} ${SAMHAIN_DB} \
+	-P ${SAMHAIN_PRT} -h ${SAMHAIN_SRV} \
+	-e 'delete from log where log_host="'${1}'";' || \
+( echo "CLEANUP FAILED" && exit 42 )
+
Index: trunk/scripts/samhain-scripts/samhain.table.rotate.pl
===================================================================
--- trunk/scripts/samhain-scripts/samhain.table.rotate.pl	(revision 1)
+++ trunk/scripts/samhain-scripts/samhain.table.rotate.pl	(revision 1)
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+#-------------------------------------------------------------------------#
+# Author: Simon Bailey, <simon.bailey@uibk.ac.at>                         #
+#                                                                         #
+# table rotation script for shifting data from the main table to keep     #
+# yule/samhain/beltane happy and fast.                                    #
+# the main reason for this is that we had 62568 log entries after         #
+# less than a week of real work with yule/samhain/beltane                 #
+# this script takes all data which is older than a day and acknowledged   #
+# and inserts it into a backup table, also in the main database.          #
+#-------------------------------------------------------------------------#
+
+use DBI;
+
+# Configuration Variables
+$SAMHAIN_DB='samhain';
+$SAMHAIN_SRV='localhost';
+$SAMHAIN_PRT='3306';
+$SAMHAIN_USR='samhain';
+$SAMHAIN_PWD='*******';
+
+# GMT Offset -- change this to your GMT Offset.
+# CET = +1
+$GMT_OFFSET = 1;
+
+# get the current date in GMT time, then convert it to yesterday
+($sec,$min,$hr,$day,$mon,$year,$wday,$ytag,$isdst) = gmtime(time);
+
+# year is returned as real year - 1900...
+$realYear = ($year-100+2000);
+$realMonth = ($mon+1); # month is a zero base array
+$realHour = ($hr+$GMT_OFFSET);
+$yesterday = ($day-1);
+
+$dbh = DBI->connect("DBI:mysql:database=$SAMHAIN_DB;host=$SAMHAIN_SRV;port=$SAMHAIN_PRT",$SAMHAIN_USR,$SAMHAIN_PWD);
+
+$sth = $dbh->prepare("INSERT INTO log_backup SELECT * FROM log WHERE ((log_ref IS NULL AND entry_status!=\'NEW\') OR (log_ref IS NOT NULL)) AND log_time < \'$realYear-$realMonth-$yesterday $realHour:00:00\';");
+$sth->execute;
+
+# print "insert done";
+
+$sth = $dbh->prepare("DELETE FROM log WHERE ((log_ref IS NULL AND entry_status!=\'NEW\') OR (log_ref IS NOT NULL)) AND log_time < \'$realYear-$realMonth-$yesterday $realHour:00:00\';");
+$sth->execute;
+
+# print "delete done";
Index: trunk/scripts/samhain.ebuild.in
===================================================================
--- trunk/scripts/samhain.ebuild.in	(revision 584)
+++ trunk/scripts/samhain.ebuild.in	(revision 1)
@@ -69,5 +69,5 @@
 	dodoc docs/BUGS COPYING docs/Changelog LICENSE docs/README \
 	      docs/README.UPGRADE docs/sh_mounts.txt docs/sh_userfiles.txt \
-	      docs/MANUAL-2_4.ps docs/MANUAL-2_4.html.tar
+	      docs/MANUAL-2_0.ps docs/MANUAL-2_0.html.tar
 
 	dohtml docs/HOWTO-client+server.html docs/HOWTO-samhain+GnuPG.html \
Index: trunk/scripts/samhain.spec.in
===================================================================
--- trunk/scripts/samhain.spec.in	(revision 584)
+++ trunk/scripts/samhain.spec.in	(revision 1)
@@ -70,5 +70,5 @@
         # Activate boot-time start up
         cd %{_localstatedir}/lib/%{name}
-        /bin/sh ./samhain-install.sh --verbose install-boot
+        ./samhain-install.sh --verbose install-boot
         if test -f /sbin/chkconfig; then
 		/sbin/chkconfig --add samhain
@@ -100,5 +100,5 @@
         cd %{_localstatedir}/lib/samhain
         if [ -f ./samhain-install.sh ]; then
-	    /bin/sh ./samhain-install.sh --verbose uninstall-boot
+	    ./samhain-install.sh --verbose uninstall-boot
 	else
 	    if [ -f /sbin/chkconfig ]; then
@@ -109,4 +109,11 @@
 fi
 
+%postun
+if [ "$1" = 0 ]; then
+        # remove any kernel modules that might have been installed
+        RVER=`uname -r`
+        rm -f /lib/modules/$RVER/samhain*
+fi
+
 
 %files
@@ -114,11 +121,10 @@
 %dir %{_localstatedir}/run
 %dir %{_localstatedir}/log
-%doc docs/BUGS COPYING docs/Changelog 
-%doc LICENSE docs/HOWTO* docs/MANUAL-2_4.* docs/README*
+%doc docs/BUGS COPYING docs/Changelog docs/TODO
+%doc LICENSE docs/HOWTO* docs/MANUAL-2_0.* docs/README*
 %{_localstatedir}/lib/%{name}
 %{_sbindir}/%{name}
 %attr(644,root,root) %{_mandir}/man5/samhain*
 %attr(644,root,root) %{_mandir}/man8/samhain*
-%attr(644,root,root) /etc/logrotate.d/@install_name@
 %config(noreplace) %{_sysconfdir}/samhainrc
 
Index: trunk/scripts/samhainadmin-gpg.pl.in
===================================================================
--- trunk/scripts/samhainadmin-gpg.pl.in	(revision 584)
+++ 	(revision )
@@ -1,726 +1,0 @@
-#! /usr/bin/perl
-
-# Copyright Rainer Wichmann (2004)
-#
-# License Information:
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-use warnings;
-use strict;
-use Getopt::Long;
-use File::Basename;
-use File::Copy;
-use File::stat;
-use File::Temp qw/ tempfile tempdir unlink0 /;
-use IO::Handle;
-use Fcntl qw(:DEFAULT :flock);
-use Tie::File;
-
-# Do I/O to the data file in binary mode (so it 
-# wouldn't complain about invalid UTF-8 characters).
-use bytes;
-
-File::Temp->safe_level( File::Temp::HIGH );
-
-my %opts = ();
-my $action;
-my $file1;
-my $file2;
-my $passphrase;
-my $secretkeyring;
-my $return_from_sign = 0;
-my $no_print_examine = 0;
-my $no_remove_lock   = 0;
-my $base = basename($0);
-
-my $cfgfile  = "@myconffile@";
-my $datafile = "@mydatafile@";
-my $daemon   = "@sbindir@/@install_name@";
-my $gpg      = "@mygpg@";
-
-my $TARGETKEYID = "@mykeyid@";
-my $KEYTAG      = "@mykeytag@";
-
-$cfgfile  =~ s/^REQ_FROM_SERVER//;
-$datafile =~ s/^REQ_FROM_SERVER//;
-
-$gpg = "gpg" if ($gpg eq "");
-
-sub check_gpg_agent() {
-    my  $gpgconf = "$ENV{'HOME'}/.gnupg/gpg.conf";
-
-    if (!-f "$gpgconf") {
-	$gpgconf = "$ENV{'HOME'}/.gnupg/options";
-    }
-
-    if (-f $gpgconf) {
-
-	my @array = ();
-	tie @array, 'Tie::File', $gpgconf or die "Cannot tie ${gpgconf}: $!";
-	my @grep = grep(/^\s*use-agent/, @array);
-	
-	# print "matches = $#grep\n";
-	
-	if ($#grep >= 0)
-	{
-	    if (exists $ENV{'GPG_AGENT_INFO'})
-	    {
-		my $socke = $ENV{'GPG_AGENT_INFO'};
-		$socke =~ s/:.*//;
-		
-		# print "socke = $socke\n";
-		
-		if (! -S $socke)
-		{
-		    print "--------------------------------------------------\n";
-		    print "\n";
-		    print " GPG is set to use gpg-agent, but GPG agent is";
-		    print " not running, though GPG_AGENT_INFO is defined.\n\n";
-		    print " Please restart gpg-agent, or remove the use-agent\n";
-		    print " option from ${gpgconf} and unset GPG_AGENT_INFO\n\n";
-		    print "--------------------------------------------------\n";
-		    print "\n";
-		    exit 1;
-		}
-	    }
-	    else
-	    {
-		print "--------------------------------------------------\n";
-		print "\n";
-		print " GPG is set to use gpg-agent, but ";
-		print " GPG_AGENT_INFO is not defined.\n\n";
-		print " Please start gpg-agent, or remove the use-agent\n";
-		print " option from ${gpgconf}\n\n";
-		print "--------------------------------------------------\n";
-		print "\n";
-		exit 1;
-	    }
-	}
-	untie @array;
-    }
-}
-
-
-sub usage() {
-    print "Usage:\n";
-    print "  $base { -m F | --create-cfgfile }    [options] [in.cfgfile]\n";
-    print "    Sign the configuration file. If in.cfgfile is given, sign it\n";
-    print "    and install it as configuration file.\n\n";
-
-    print "  $base { -m f | --print-cfgfile }     [options] \n";
-    print "    Print the configuration file to stdout. Signatures are removed.\n\n";
-
-    print "  $base { -m D | --create-datafile }   [options] [in.datafile]\n";
-    print "    Sign the database file. If in.datafile is given, sign it\n";
-    print "    and install it as database file.\n\n";
-
-    print "  $base { -m d | --print-datafile }    [options] \n";
-    print "    Print the database file to stdout. Signatures are removed. Use\n";
-    print "    option --list to list files in database rather than printing the raw file.\n\n";
-
-    print "  $base { -m R | --remove-signature }  [options] file1 [file2 ...]\n";
-    print "    Remove cleartext signature from input file(s). The file\n";
-    print "    is replaced by the non-signed file.\n\n";
-
-    print "  $base { -m E | --sign }              [options] file1 [file2 ...]\n";
-    print "    Sign file(s) with a cleartext signature. The file\n";
-    print "    is replaced by the signed file.\n\n";
-
-    print "  $base { -m e | --examine }           [options] file1 [file2 ...]\n";
-    print "    Report signature status of file(s).\n\n";
-
-    print "  $base { -m G | --generate-keys }     [options] \n";
-    print "    Generate a PGP keypair to use for signing.\n\n";
-
-    print "Options:\n";
-    print "  -c cfgfile    --cfgfile cfgfile\n";
-    print "    Select an alternate configuration file.\n\n";
-
-    print "  -d datafile   --datafile datafile\n";
-    print "    Select an alternate database file.\n\n";
-
-    print "  -p passphrase --passphrase passphrase\n";
-    print "    Set the passphrase for gpg. By default, gpg will ask.\n\n";
-
-    print "  -s gnupg_homedir --secretkeyring gnupg_homedir\n";
-    print "    Select an alternate gpg homedirectory to locate the secret keyring.\n";
-    print "    Will use '$ENV{'HOME'}/.gnupg/' by default.\n\n";
-
-    print "  -k keyid      --keyid keyid\n";
-    print "   Select the keyid to use for signing.\n\n";
-
-    print "  -l            --list\n";
-    print "    List the files in database rather than printing the raw file.\n\n";
-
-    print "  -v            --verbose\n";
-    print "    Verbose output.\n\n";
-    return;
-}
-
-sub check_gpg_uid () {
-    if (0 != $>) {
-	print "--------------------------------------------------\n";
-	print "\n";
-	print " You are not root. Please remember that samhain/yule\n";
-	print " will use the public keyring of root to verify a signature.\n";
-	print "\n";
-	print "--------------------------------------------------\n";
-    } else {
-	if (!("@yulectl_prg@" =~ //)) {
-	    print "--------------------------------------------------\n";
-	    print "\n";
-	    print " Please remember that yule will drop root after startup. Signature\n";
-	    print " verification on SIGHUP will fail if you do not import the public key\n";
-	    print " into the keyring of the non-root yule user.\n";
-	    print "\n";
-	    print "--------------------------------------------------\n";
-	}
-    }
-}
-    
-sub check_gpg_sign () {
-    if ( defined($secretkeyring)) {
-        if ( (!-d "$secretkeyring")){
-            print "--------------------------------------------------\n";
-            print "\n";
-            print " Secret keyring $secretkeyring not found!\n";
-            print "\n";
-            print " Please check the path/name of the alternate secret keyring.\n";
-            print "\n";
-            print "--------------------------------------------------\n";
-            print "\n";
-            exit;
-        }
-    } else {
-        if ( (!-d "$ENV{'HOME'}/.gnupg") || (!-e "$ENV{'HOME'}/.gnupg/secring.gpg")) {
-	    print "--------------------------------------------------\n";
-	    print "\n";
-	    if (!-d "$ENV{'HOME'}/.gnupg") {
-	        print " Directory \$HOME/.gnupg not found!\n";
-	    } else {
-	        print " Secret keyring \$HOME/.gnupg/secring.gpg not found!\n";
-	    }
-	    print "\n";
-	    print " This indicates that you have never created a \n";
-	    print " public/private keypair, and thus cannot sign.\n";
-	    print " \n";
-	    print " Please use $0 --generate-keys or gpg --gen-key\n";
-	    print " to generate a public/private keypair first.\n";
-	    print "\n";
-	    print "--------------------------------------------------\n";
-	    print "\n";
-	    exit;
-        }
-    }
-}
-
-sub check_gpg_verify () {
-    if ( (!-d "$ENV{'HOME'}/.gnupg") || (!-e "$ENV{'HOME'}/.gnupg/pubring.gpg")) {
-	print "--------------------------------------------------\n";
-	print "\n";
-	if (!-d "$ENV{'HOME'}/.gnupg") {
-	    print " Directory \$HOME/.gnupg not found!\n";
-	} else {
-	    print " Public keyring \$HOME/.gnupg/pubring.gpg not found!\n";
-	}
-	print "\n";
-	print " This indicates that you have never used gpg before \n";
-	print " and/or have no public keys to verify signatures.\n";
-	print " \n";
-	print " Please use 'gpg --export key_id' to export the public\n";
-	print " signing key of the user who is signing the\n";
-	print " configuration/database files.\n\n";
-	print " Then you can use 'gpg --import keyfile' to import the key\n";
-	print " into this user's public keyring.\n";
-	print "\n";
-	print "--------------------------------------------------\n";
-	print "\n";
-	exit;
-    }
-}
-
-
-sub generate () {
-    my $command = "$gpg --homedir $ENV{'HOME'}/.gnupg --gen-key";
-    check_gpg_uid();
-    system ($command) == 0 
-	or die "system $command failed: $?";
-    exit;
-}
-
-sub examine () {
-    my $iscfg = 0;
-    my $have_fp  = 0;
-    my $have_sig = 0;
-    my $message = '';
-    my $retval  = 9;
-    my $fh;
-    my $filename;
-
-    if (!($file1 =~ /^\-$/)) {
-	die ("Cannot open $file1 for read: $!") unless ((-e $file1) && (-r _));
-    }
-    open FIN,  "<$file1" or die "Cannot open $file1 for read: $!";
-
-    my $dir = tempdir( CLEANUP => 1 );
-    $filename = $dir . "/exa_jhfdbilw." . $$;
-    open $fh, ">$filename" or die "Cannot open $filename";
-    autoflush $fh 1;
-
-    while (<FIN>) {
-	print $fh $_;
-	if ($_ =~ /^\s*\[Misc\]/) {
-	    $iscfg = 1;
-	}
-    }
-    if ($iscfg == 1) {
-	$message .=  "File $file1 is a configuration file\n\n";
-    } else {
-	$message .=  "File $file1 is a database file\n\n";
-    }
-
-
-    my $command = "$gpg --homedir $ENV{'HOME'}/.gnupg --status-fd 1 ";
-    $command .= "--verbose " if (defined($opts{'v'}));
-    $command .= "--verify $filename ";
-    if (defined($opts{'v'})) {
-	$command .= "2>&1";
-    } else {
-	$command .= "2>/dev/null";
-    }
-
-    print STDOUT "Using: $command\n\n" if (defined($opts{'v'}));
-    open  GPGIN, "$command |" or die "Cannot fork: $!";
-
-    while (<GPGIN>) {
-	if ($_ =~ /^\[GNUPG:\] GOODSIG ([0-9A-F]+) (.*)$/) {
-	    $message .= "GOOD signature with key: $1\n";
-	    $message .= "Key owner:               $2\n";
-	    $have_sig = 1;
-	    $retval   = 0;
-	}
-	if ($_ =~ /^\[GNUPG:\] VALIDSIG ([0-9A-F]+) ([0-9\-]+)\s/) {
-	    $message .= "Key fingerprint:         $1\n";
-	    $message .= "Signature generated on:  $2\n\n";
-	    $have_fp = 1;
-	    $message .=  "This file is signed with a valid signature.\n" 
-		if ($have_sig == 1);
-	    $have_sig = 1;
-	    $have_fp = 1;
-	}
-	if ($_ =~ /^\[GNUPG:\] NODATA 1/) {
-	    $message .=  "NO signature found.\n\n";
-	    $message .=  "This file is not signed !!!\n";
-	    $have_sig = 1;
-	    $have_fp = 1;
-	    $retval  = 2;
-	}
-	if ($_ =~ /^\[GNUPG:\] BADSIG ([0-9A-F]+) (.*)$/) {
-	    $message .=  "BAD signature with key: $1\n";
-	    $message .=  "Key owner:              $2\n\n";
-	    $message .=  "This file is signed with an invalid signature !!!\n";
-	    $have_sig = 1;
-	    $have_fp = 1;
-	    $retval = 1;
-	}
-	if ($_ =~ /^\[GNUPG:\] NO_PUBKEY ([0-9A-F]+)/) {
-	    $message .=  "NOT CHECKED signature with key: $1\n\n";
-	    $message .=  "The signature of this file cannot be checked: no public key available !!!\n";
-	    $have_sig = 1;
-	    $have_fp = 1;
-	    $retval  = 1;
-	}
-	print STDOUT $_ if (defined($opts{'v'}));
-    }
-    close (GPGIN);
-    print STDOUT "\n" if (defined($opts{'v'}));
-    if ($have_sig == 0) {
-	$message .=  "NO valid signature found\n";
-    } 
-    elsif ($have_fp == 0) {
-	$message .=  "NO fingerprint found\n";
-    }
-    close (FIN);
-    if ($no_print_examine == 0) {
-	print STDOUT $message;
-    }
-    unlink0( $fh, $filename ) or die "Cannot unlink $filename safely";
-    return $retval;
-}
-
-sub remove () {
-    my $bodystart = 1;
-    my $sigstart  = 0;
-    my $sigend    = 0;
-    my $filename  = "";
-    my $fh;
-    my $stats;
-
-    open FH, "<$file1" or die "Cannot open file $file1 for read: $!";
-    if (!($file1 =~ /^\-$/)) {
-	flock(FH, LOCK_EX) unless ($no_remove_lock == 1);
-	my $dir = tempdir( CLEANUP => 1 ) or die "Tempdir failed";
-	$filename = $dir . "/rem_iqegBCQb." . $$;
-	open $fh, ">$filename" or die "Cannot open $filename";
-	$stats = stat($file1);
-	# ($fh, $filename) = tempfile(UNLINK => 1);
-    } else {
-	open $fh, ">$file1" or die "Cannot open file $file1 for write: $!";
-    }
-    autoflush $fh 1;
-    while (<FH>) {
-	if ($_ =~ /^-----BEGIN PGP SIGNED MESSAGE-----/) {
-	    $sigstart = 1;
-	    $bodystart = 0;
-	    next;
-	} elsif (($sigstart == 1) && ($_ =~ /^\s+$/)) {
-	    $sigstart = 0;
-	    $bodystart = 1;
-	    next;
-	} elsif ($_ =~ /^-----BEGIN PGP SIGNATURE-----/) {
-	    $bodystart = 0;
-	    $sigend = 1;
-	    next;
-	} elsif (($sigend == 1) && ($_ =~ /^-----END PGP SIGNATURE-----/)) {
-	    $sigend = 0;
-	    $bodystart = 1;
-	    next;
-	}
-	if ($bodystart == 1) {
-	    print $fh $_;
-	}
-    }
-    if (!($file1 =~ /^\-$/)) {
-	copy("$filename", "$file1") 
-	    or die "Copy $filename to $file1 failed: $!";
-	chmod $stats->mode, $file1;
-	chown $stats->uid, $stats->gid, $file1;
-	flock(FH, LOCK_UN) unless ($no_remove_lock == 1);
-	close FH;
-    }
-    unlink0( $fh, $filename ) or die "Cannot unlink $filename safely";
-    return;
-}
-
-sub print_cfgfile () {
-    my $bodystart = 0;
-    my $sigstart  = 0;
-
-    if (!defined($file2)) {
-	$file2 = '-';
-    }
-
-    open FH, "<$file1" or die "Cannot open file $file1 for read: $!";
-    open FO, ">$file2" or die "Cannot open file $file2 for write: $!";
-    while (<FH>) {
-	if ($_ =~ /^-----BEGIN PGP SIGNED MESSAGE-----/) {
-	    $sigstart = 1;
-	    next;
-	} elsif (($sigstart == 1) && ($_ =~ /^\s+$/)) {
-	    $sigstart = 0;
-	    $bodystart = 1;
-	    next;
-	} elsif ($_ =~ /^-----BEGIN PGP SIGNATURE-----/) {
-	    $bodystart = 0;
-	    exit;
-	}
-	if ($bodystart == 1) {
-	    print FO $_;
-	}
-    }
-    exit;
-}
-sub print_datafile () {
-    die ("Cannot find program $daemon") 
-	unless (-e $daemon);
-    if (defined($opts{'v'})) {
-	open FH, "$daemon --full-detail -d $datafile |" 
-	    or die "Cannot open datafile $datafile for read: $!";
-    } else {
-	open FH, "$daemon -d $datafile |" 
-	    or die "Cannot open datafile $datafile for read: $!";
-    }
-    while (<FH>) {
-	print $_;
-    }
-    exit;
-}
-
-sub sign_file () {
-
-    my $fileout = '';
-    my $bodystart = 1;
-    my $sigstart  = 0;
-    my $sigend    = 0;
-    my $stats;
-    my $fh1;
-    my $filename1;
-    my $flag1     = 0;
-
-    check_gpg_uid();
-    check_gpg_agent();
-
-    if (!defined($file2)) {
-	$file2 = $file1;
-    }
-
-    if ($file1 =~ /^\-$/) {
-	my $dir = tempdir( CLEANUP => 1 ) or die "Tempdir failed";
-	$filename1 = $dir . "/sig_vs8827sd." . $$;
-	open $fh1, ">$filename1" or die "Cannot open $filename1";
-	$flag1 = 1;
-	# my ($fh1, $filename1) = tempfile(UNLINK => 1);
-
-	while (<STDIN>) {
-	  if ($_ =~ /^-----BEGIN PGP SIGNED MESSAGE-----/) {
-	    $sigstart = 1;
-	    $bodystart = 0;
-	    next;
-	  } elsif (($sigstart == 1) && ($_ =~ /^\s+$/)) {
-	    $sigstart = 0;
-	    $bodystart = 1;
-	    next;
-	  } elsif ($_ =~ /^-----BEGIN PGP SIGNATURE-----/) {
-	    $bodystart = 0;
-	    $sigend = 1;
-	    next;
-	  } elsif (($sigend == 1) && ($_ =~ /^-----END PGP SIGNATURE-----/)) {
-	    $sigend = 0;
-	    $bodystart = 1;
-	    next;
-	  }
-	  if ($bodystart == 1) {
-	    print $fh1 $_;
-	  }
-	  #
-	  # print $fh1 $_;
-	  #
-	}
-	$file1 = $filename1;
-	$fileout = '-';
-    } else {
-	open (LOCKFILE, "<$file1") or die "Cannot open $file1: $!";
-	flock(LOCKFILE, LOCK_EX);
-	$no_print_examine = 1;
-	$no_remove_lock   = 1;
-	if (examine() < 2) {
-	    remove();
-	}
-	$fileout = $file1 . ".asc";
-	$stats   = stat($file1)
-	    or die "No file $file1: $!";
-    }
-
-    if (defined($passphrase)) {
-	local $SIG{PIPE} = 'IGNORE';
-	my $command = "$gpg --homedir $ENV{'HOME'}/.gnupg --passphrase-fd 0 -a ${KEYTAG} ${TARGETKEYID} --clearsign -o $fileout --not-dash-escaped ";
-        $command .= "--secret-keyring $secretkeyring " if (defined($opts{'s'}));
-	$command .= "$file1";
-	open (FH, "|$command")  or die "can't fork: $!";
-	print FH "$passphrase"  or die "can't write: $!";
-	close FH                or die "can't close: status=$?";
-    } else {
-	my $command = "$gpg --homedir $ENV{'HOME'}/.gnupg                   -a ${KEYTAG} ${TARGETKEYID} --clearsign -o $fileout --not-dash-escaped ";
-        $command .= "--secret-keyring $secretkeyring " if (defined($opts{'s'}));
-	$command .= "$file1";
-	system("$command") == 0 
-	    or die "system $command failed: $?";
-    }
-
-    if (!($fileout =~ /^\-$/)) {
-	my $st_old = stat($file1) 
-	    or die "No file $file1: $!";
-	my $st_new = stat($fileout) 
-	    or die "No file $fileout: $!";
-	die ("Signed file is smaller than unsigned file") 
-	    unless ($st_new->size > $st_old->size);
-	move("$fileout", "$file2") 
-	    or die "Move $fileout to $file2 failed: $!";
-	chmod $stats->mode, $file2;
-	chown $stats->uid, $stats->gid, $file2;
-	flock(LOCKFILE, LOCK_UN);
-    }
-
-    if ($flag1 == 1) {
-	unlink0( $fh1, $filename1 ) or die "Cannot unlink $filename1 safely";
-    }
-    if ($return_from_sign == 1) {
-	return;
-    }
-    exit;
-}
-
-Getopt::Long::Configure ("posix_default");
-Getopt::Long::Configure ("bundling");
-# Getopt::Long::Configure ("debug");
-
-GetOptions (\%opts, 'm=s', 'h|help', 'v|verbose', 'l|list',
-	    'c|cfgfile=s',
-	    'd|datafile=s',
-	    'p|passphrase=s',
-	    's|secretkeyring=s',
-            'k|keyid=s',
-	    'create-cfgfile',  # -m F
-	    'print-cfgfile',   # -m f
-	    'create-datafile', # -m D
-	    'print-datafile',  # -m d
-	    'remove-signature',# -m R
-	    'sign',            # -m E
-	    'examine',         # -m e
-	    'generate-keys');  # -m G
-
-if (defined ($opts{'h'})) {
-    usage();
-    exit;
-}
-
-if (defined($opts{'k'})) {
-    $TARGETKEYID = $opts{'k'};
-    $KEYTAG = "--default-key";
-}
-if (defined($opts{'c'})) {
-    $cfgfile = $opts{'c'};
-}
-if (defined($opts{'d'})) {
-    $datafile = $opts{'d'};
-}
-if (defined($opts{'p'})) {
-    $passphrase = $opts{'p'};
-}
-if (defined($opts{'s'})) {
-    $secretkeyring = $opts{'s'};
-}
-
-if (defined ($opts{'m'}) && ($opts{'m'} =~ /[FfDdREeG]{1}/) ) {
-    $action = $opts{'m'};
-}
-elsif (defined ($opts{'create-cfgfile'})) {
-    $action = 'F';
-}
-elsif (defined ($opts{'print-cfgfile'})) {
-    $action = 'f';
-}
-elsif (defined ($opts{'create-datafile'})) {
-    $action = 'D';
-}
-elsif (defined ($opts{'print-datafile'})) {
-    $action = 'd';
-}
-elsif (defined ($opts{'remove-signature'})) {
-    $action = 'R';
-}
-elsif (defined ($opts{'sign'})) {
-    $action = 'E';
-}
-elsif (defined ($opts{'examine'})) {
-    $action = 'e';
-}
-elsif (defined ($opts{'generate-keys'})) {
-    $action = 'G';
-}
-else {
-    usage();
-    die ("No valid action specified !");
-}
-
-if (defined($ARGV[0])) {
-    $file1 = $ARGV[0];
-} 
-if (defined($ARGV[1])) {
-    $file2 = $ARGV[1];
-} 
-
-
-if (($action =~ /[REe]{1}/) && !defined($file1)) {
-    usage();
-    die("Option -m $action requires a filename (or '-' for stdio)\n");
-}
-
-if ($action =~ /^F$/) {
-    if (!defined($file1)) {
-	$file1 = $cfgfile;
-    }
-    $file2 = $cfgfile;
-    sign_file ();
-}
-
-if ($action =~ /^D$/) {
-    if (!defined($file1)) {
-	$file1 = $datafile;
-    }
-    $file2 = $datafile;
-    sign_file ();
-}
-
-if ($action =~ /^R$/) {
-    # $file1 defined
-    my $i = 0;
-    while (defined($ARGV[$i])) {
-	$file1 = $ARGV[$i];
-	remove ();
-	++$i;
-    }
-}
-
-if ($action =~ /^E$/) {
-    # $file1 defined
-    # default: $file2 = $file1
-    check_gpg_sign();
-    my $i = 0;
-    while (defined($ARGV[$i])) {
-	$file1 = $ARGV[$i];
-	$file2 = $file1;
-	$return_from_sign = 1;
-	sign_file ();
-	++$i;
-    }
-}
-
-if ($action =~ /^e$/) {
-    # $file1 defined
-    # default: $file2 = stdout
-    check_gpg_verify();
-    my $i = 0;
-    my $ret = 0;
-    while (defined($ARGV[$i])) {
-	print "\n";
-	$file1 = $ARGV[$i];
-	$ret += examine ();
-	++$i;
-	print "\n--------------------------------\n" if (defined($ARGV[$i]));
-    }
-    exit($ret);
-}
-
-if ($action =~ /^f$/) {
-    $file1 = $cfgfile;
-    $file2 = "-";
-    print_cfgfile ();
-}
-
-if ($action =~ /^d$/) {
-    # $file1 irrelevant
-    if (defined($opts{'l'})) {
-	print_datafile ();
-    } else {
-	$file1 = $datafile;
-	$file2 = "-";
-	print_cfgfile ();
-    }
-}
-
-
-
Index: trunk/scripts/samhainadmin-sig.pl.in
===================================================================
--- trunk/scripts/samhainadmin-sig.pl.in	(revision 584)
+++ 	(revision )
@@ -1,636 +1,0 @@
-#! /usr/bin/perl
-
-# Copyright Rainer Wichmann (2004)
-#
-# License Information:
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-use warnings;
-use strict;
-use Getopt::Long;
-use File::Basename;
-use File::Copy;
-use File::stat;
-use File::Temp qw/ tempfile tempdir unlink0 /;
-use IO::Handle;
-use Fcntl qw(:DEFAULT :flock);
-use Tie::File;
-
-# Do I/O to the data file in binary mode (so it 
-# wouldn't complain about invalid UTF-8 characters).
-use bytes;
-
-File::Temp->safe_level( File::Temp::HIGH );
-
-my %opts = ();
-my $action;
-my $file1;
-my $file2;
-my $passphrase;
-my $secretkey;
-my $return_from_sign = 0;
-my $no_print_examine = 0;
-my $no_remove_lock   = 0;
-my $base = basename($0);
-
-my $cfgfile  = "@myconffile@";
-my $datafile = "@mydatafile@";
-my $daemon   = "@sbindir@/@install_name@";
-my $signify  = "@mysignify@";
-
-my $SIGDIR   = "$ENV{'HOME'}/.signify";
-my $KEYID    = "@install_name@";
-
-$cfgfile  =~ s/^REQ_FROM_SERVER//;
-$datafile =~ s/^REQ_FROM_SERVER//;
-
-$signify = "signify-openbsd" if ($signify eq "");
-
-sub usage() {
-    print "Usage:\n";
-    print "  $base { -m F | --create-cfgfile }    [options] [in.cfgfile]\n";
-    print "    Sign the configuration file. If in.cfgfile is given, sign it\n";
-    print "    and install it as configuration file.\n\n";
-
-    print "  $base { -m f | --print-cfgfile }     [options] \n";
-    print "    Print the configuration file to stdout. Signatures are removed.\n\n";
-
-    print "  $base { -m D | --create-datafile }   [options] [in.datafile]\n";
-    print "    Sign the database file. If in.datafile is given, sign it\n";
-    print "    and install it as database file.\n\n";
-
-    print "  $base { -m d | --print-datafile }    [options] \n";
-    print "    Print the database file to stdout. Signatures are removed. Use\n";
-    print "    option --list to list files in database rather than printing the raw file.\n\n";
-
-    print "  $base { -m R | --remove-signature }  [options] file1 [file2 ...]\n";
-    print "    Remove cleartext signature from input file(s). The file\n";
-    print "    is replaced by the non-signed file.\n\n";
-
-    print "  $base { -m E | --sign }              [options] file1 [file2 ...]\n";
-    print "    Sign file(s) with a cleartext signature. The file\n";
-    print "    is replaced by the signed file.\n\n";
-
-    print "  $base { -m e | --examine }           [options] file1 [file2 ...]\n";
-    print "    Report signature status of file(s).\n\n";
-
-    print "  $base { -m G | --generate-keys }     [options] \n";
-    print "    Generate a signify keypair to use for signing.\n\n";
-
-    print "Options:\n";
-    print "  -c cfgfile    --cfgfile cfgfile\n";
-    print "    Select an alternate configuration file.\n\n";
-
-    print "  -d datafile   --datafile datafile\n";
-    print "    Select an alternate database file.\n\n";
-
-    print "  -p passphrase --passphrase passphrase\n";
-    print "    Set the passphrase for signify. By default, signify will ask.\n\n";
-
-    print "  -s signify_dir --signify-dir signify_dir\n";
-    print "    Select an alternate directory to locate the secret keyring.\n";
-    print "    Will use '$ENV{'HOME'}/.signify/' by default.\n\n";
-
-    print "  -k keyid      --keyid keyid\n";
-    print "   Select the keyid to use for signing.\n\n";
-
-    print "  -l            --list\n";
-    print "    List the files in database rather than printing the raw file.\n\n";
-
-    print "  -v            --verbose\n";
-    print "    Verbose output.\n\n";
-    return;
-}
-
-sub check_signify_uid () {
-    if (0 != $>) {
-	print "--------------------------------------------------\n";
-	print "\n";
-	print " You are not root. Please remember that samhain/yule\n";
-	print " will use the public key of root to verify a signature.\n";
-	print "\n";
-	print "--------------------------------------------------\n";
-    } else {
-	if (!("@yulectl_prg@" =~ //)) {
-	    print "--------------------------------------------------\n";
-	    print "\n";
-	    print " Please remember that yule will drop root after startup. Signature\n";
-	    print " verification on SIGHUP will fail if you do not import the public key\n";
-	    print " into the ~/.signify/ directory of the non-root yule user.\n";
-	    print "\n";
-	    print "--------------------------------------------------\n";
-	}
-    }
-}
-    
-sub check_signify_sign () {
-    if ( defined($secretkey)) {
-        if ( (!-d "$secretkey")){
-            print "--------------------------------------------------\n";
-            print "\n";
-            print " Secret key $secretkey not found!\n";
-            print "\n";
-            print " Please check the path/name of the alternate secret key.\n";
-            print "\n";
-            print "--------------------------------------------------\n";
-            print "\n";
-            exit;
-        }
-    } else {
-        if ( (!-d "$SIGDIR") || (!-e "${SIGDIR}/${KEYID}.sec")) {
-	    print "--------------------------------------------------\n";
-	    print "\n";
-	    if (!-d "$SIGDIR") {
-	        print " Directory $SIGDIR not found!\n";
-	    } else {
-	        print " Secret key ${SIGDIR}/${KEYID}.sec not found!\n";
-	    }
-	    print "\n";
-	    print " This indicates that you have never created a \n";
-	    print " public/private keypair, and thus cannot sign.\n";
-	    print " \n";
-	    print " Please use $0 --generate-keys or\n";
-	    print " $signify -G -s ${SIGDIR}/${KEYID}.sec -p ${SIGDIR}/${KEYID}.pub\n";
-	    print " to generate a public/private keypair first.\n";
-	    print "\n";
-	    print "--------------------------------------------------\n";
-	    print "\n";
-	    exit;
-        }
-    }
-}
-
-sub check_signify_verify () {
-    if ( (!-d "${SIGDIR}") || (!-e "${SIGDIR}/${KEYID}.pub")) {
-	print "--------------------------------------------------\n";
-	print "\n";
-	if (!-d "$SIGDIR") {
-	    print " Directory $SIGDIR not found!\n";
-	} else {
-	    print " Public key ${SIGDIR}/${KEYID}.pub not found!\n";
-	}
-	print "\n";
-	print " This indicates that you have no public key\n";
-	print " to verify signatures.\n";
-	print " \n";
-	print " Please copy the public key ${KEYID}.pub of\n";
-	print " the user who is signing the configuration/database files\n";
-	print " into the directory $SIGDIR.\n";
-	print "\n";
-	print "--------------------------------------------------\n";
-	print "\n";
-	exit;
-    }
-}
-
-
-sub generate () {
-    my $command = "$signify -G -s ${SIGDIR}/${KEYID}.sec -p ${SIGDIR}/${KEYID}.pub";
-    if (!-d "${SIGDIR}") {
-	unless(mkdir "$SIGDIR", 0750) {
-	    die "Creating directory $SIGDIR failed: $?";
-	}
-    }
-    check_signify_uid();
-    system ($command) == 0 
-	or die "system $command failed: $?";
-    exit;
-}
-
-sub examine () {
-    my $iscfg = 0;
-    my $have_fp  = 0;
-    my $have_sig = 0;
-    my $message = '';
-    my $retval  = 9;
-    my $fh;
-    my $filename;
-
-    if (!($file1 =~ /^\-$/)) {
-	die ("Cannot open $file1 for read: $!") unless ((-e $file1) && (-r _));
-    }
-    open FIN,  "<$file1" or die "Cannot open $file1 for read: $!";
-
-    my $dir = tempdir( CLEANUP => 1 );
-    $filename = $dir . "/exa_jhfdbilw." . $$;
-    open $fh, ">$filename" or die "Cannot open $filename";
-    autoflush $fh 1;
-
-    while (<FIN>) {
-	print $fh $_;
-	if ($_ =~ /^\s*\[Misc\]/) {
-	    $iscfg = 1;
-	}
-    }
-    if ($iscfg == 1) {
-	$message .=  "File $file1 is a configuration file\n\n";
-    } else {
-	$message .=  "File $file1 is a database file\n\n";
-    }
-
-
-    my $command = "$signify -Vem /dev/null -p ${SIGDIR}/${KEYID}.pub ";
-    $command .= "-x $filename ";
-    if (defined($opts{'v'})) {
-	$command .= "2>&1";
-    } else {
-	$command .= "2>/dev/null";
-    }
-
-    print STDOUT "Using: $command\n\n" if (defined($opts{'v'}));
-    open  SIGIN, "$command |" or die "Cannot fork: $!";
-
-    while (<SIGIN>) {
-	chomp ($_);
-	if ($_ =~ /^Signature Verified$/) {
-	    $message .= "GOOD signature with key: ${SIGDIR}/${KEYID}.pub\n";
-	    $have_sig = 1;
-	    $retval   = 0;
-	}
-	print STDOUT $_ if (defined($opts{'v'}));
-    }
-    close (SIGIN);
-    print STDOUT "\n" if (defined($opts{'v'}));
-    if ($have_sig == 0) {
-	$message .=  "NO valid signature found\n";
-    }
-    close (FIN);
-    if ($no_print_examine == 0) {
-	print STDOUT $message;
-    }
-    unlink0( $fh, $filename ) or die "Cannot unlink $filename safely";
-    return $retval;
-}
-
-sub wstrip ($) {
-    $_ = shift;
-    $_ =~ s/\s+//g;
-    return $_;
-}
-
-sub remove () {
-    my $bodystart = 1;
-    my $sigstart  = 0;
-    my $sigend    = 0;
-    my $filename  = "";
-    my $fh;
-    my $stats;
-
-    open FH, "<$file1" or die "Cannot open file $file1 for read: $!";
-    if (!($file1 =~ /^\-$/)) {
-	flock(FH, LOCK_EX) unless ($no_remove_lock == 1);
-	my $dir = tempdir( CLEANUP => 1 ) or die "Tempdir failed";
-	$filename = $dir . "/rem_iqegBCQb." . $$;
-	open $fh, ">$filename" or die "Cannot open $filename";
-	$stats = stat($file1);
-    } else {
-	open $fh, ">$file1" or die "Cannot open file $file1 for write: $!";
-    }
-    autoflush $fh 1;
-    while (<FH>) {
-	if ($_ =~ /^untrusted comment: /) {
-	    $sigstart = 1;
-	    $bodystart = 0;
-	    next;
-	} elsif (($sigstart == 1) && (wstrip($_) =~ m{^(?: [A-Za-z0-9+/]{4} )*(?:[A-Za-z0-9+/]{2} [AEIMQUYcgkosw048]=|[A-Za-z0-9+/][AQgw]==)?$}xm )) {
-	    $sigstart = 0;
-	    $bodystart = 1;
-	    next;
-	} elsif (($sigstart == 1) && ($bodystart == 0)) {
-	    # comment NOT followed by signature
-	    $sigstart = 0;
-	    next;
-	}
-
-	if ($bodystart == 1) {
-	    print $fh $_;
-	}
-    }
-    if (!($file1 =~ /^\-$/)) {
-	copy("$filename", "$file1") 
-	    or die "Copy $filename to $file1 failed: $!";
-	chmod $stats->mode, $file1;
-	chown $stats->uid, $stats->gid, $file1;
-	flock(FH, LOCK_UN) unless ($no_remove_lock == 1);
-	close FH;
-    }
-    unlink0( $fh, $filename ) or die "Cannot unlink $filename safely";
-    return;
-}
-
-sub print_cfgfile () {
-    my $bodystart = 0;
-    my $sigstart  = 0;
-
-    if (!defined($file2)) {
-	$file2 = '-';
-    }
-
-    open FH, "<$file1" or die "Cannot open file $file1 for read: $!";
-    open FO, ">$file2" or die "Cannot open file $file2 for write: $!";
-    while (<FH>) {
-	if ($_ =~ /^untrusted comment: /) {
-	    $sigstart = 1;
-	    $bodystart = 0;
-	    next;
-	} elsif (($sigstart == 1) && (wstrip($_) =~ m{^(?: [A-Za-z0-9+/]{4} )*(?:[A-Za-z0-9+/]{2} [AEIMQUYcgkosw048]=|[A-Za-z0-9+/][AQgw]==)?$}xm )) {
-	    $sigstart = 0;
-	    $bodystart = 1;
-	    next;
-	} elsif (($sigstart == 1) && ($bodystart == 0)) {
-	    # comment NOT followed by signature 
-	    $sigstart = 0;
-	    next;
-	}
-	if ($bodystart == 1) {
-	    print FO $_;
-	}
-    }
-    exit;
-}
-
-sub print_datafile () {
-    die ("Cannot find program $daemon") 
-	unless (-e $daemon);
-    if (defined($opts{'v'})) {
-	open FH, "$daemon --full-detail -d $datafile |" 
-	    or die "Cannot open datafile $datafile for read: $!";
-    } else {
-	open FH, "$daemon -d $datafile |" 
-	    or die "Cannot open datafile $datafile for read: $!";
-    }
-    while (<FH>) {
-	print $_;
-    }
-    exit;
-}
-
-sub sign_file () {
-
-    my $fileout = '';
-    my $bodystart = 1;
-    my $sigstart  = 0;
-    my $sigend    = 0;
-    my $stats;
-    my $fh1;
-    my $filename1;
-    my $flag1     = 0;
-
-    check_signify_uid();
-
-    if (!defined($file2)) {
-	$file2 = $file1;
-    }
-
-    if ($file1 =~ /^\-$/) {
-	my $dir = tempdir( CLEANUP => 1 ) or die "Tempdir failed";
-	$filename1 = $dir . "/sig_vs8827sd." . $$;
-	open $fh1, ">$filename1" or die "Cannot open $filename1";
-	$flag1 = 1;
-	# my ($fh1, $filename1) = tempfile(UNLINK => 1);
-
-	while (<STDIN>) {
-	    if ($_ =~ /^untrusted comment: /) {
-		$sigstart = 1;
-		$bodystart = 0;
-		next;
-	    } elsif (($sigstart == 1) && (wstrip($_) =~ m{^(?: [A-Za-z0-9+/]{4} )*(?:[A-Za-z0-9+/]{2} [AEIMQUYcgkosw048]=|[A-Za-z0-9+/][AQgw]==)?$}xm )) {
-		$sigstart = 0;
-		$bodystart = 1;
-		next;
-	    } elsif (($sigstart == 1) && ($bodystart == 0)) {
-		#comment NOT followed by signature 
-		$sigstart = 0;
-		next;
-	    }
-
-	    if ($bodystart == 1) {
-		print $fh1 $_;
-	    }
-	}
-	$file1 = $filename1;
-	$fileout = '-';
-    } else {
-	open (LOCKFILE, "<$file1") or die "Cannot open $file1: $!";
-	flock(LOCKFILE, LOCK_EX);
-	$no_print_examine = 1;
-	$no_remove_lock   = 1;
-	if (examine() < 2) {
-	    remove();
-	}
-	$fileout = $file1 . ".sig";
-	$stats   = stat($file1)
-	    or die "No file $file1: $!";
-    }
-
-    my $command = "$signify -Se ";
-    $command .= "-s ${SIGDIR}/${KEYID}.sec ";
-    $command .= "-x ${fileout} ";
-    $command .= "-m $file1";
-
-    if (defined($passphrase)) {
-	local $SIG{PIPE} = 'IGNORE';
-	open (FH, "|$command")  or die "can't fork: $!";
-	print FH "$passphrase"  or die "can't write: $!";
-	close FH                or die "can't close: status=$?";
-    } else {
-	system("$command") == 0 
-	    or die "system $command failed: $?";
-    }
-
-    if (!($fileout =~ /^\-$/)) {
-	my $st_old = stat($file1) 
-	    or die "No file $file1: $!";
-	my $st_new = stat($fileout) 
-	    or die "No file $fileout: $!";
-	die ("Signed file is smaller than unsigned file") 
-	    unless ($st_new->size > $st_old->size);
-	move("$fileout", "$file2") 
-	    or die "Move $fileout to $file2 failed: $!";
-	chmod $stats->mode, $file2;
-	chown $stats->uid, $stats->gid, $file2;
-	flock(LOCKFILE, LOCK_UN);
-    }
-
-    if ($flag1 == 1) {
-	unlink0( $fh1, $filename1 ) or die "Cannot unlink $filename1 safely";
-    }
-    if ($return_from_sign == 1) {
-	return;
-    }
-    exit;
-}
-
-Getopt::Long::Configure ("posix_default");
-Getopt::Long::Configure ("bundling");
-# Getopt::Long::Configure ("debug");
-
-GetOptions (\%opts, 'm=s', 'h|help', 'v|verbose', 'l|list',
-	    'c|cfgfile=s',
-	    'd|datafile=s',
-	    'p|passphrase=s',
-	    's|secretkey=s',
-            'k|keyid=s',
-	    'create-cfgfile',  # -m F
-	    'print-cfgfile',   # -m f
-	    'create-datafile', # -m D
-	    'print-datafile',  # -m d
-	    'remove-signature',# -m R
-	    'sign',            # -m E
-	    'examine',         # -m e
-	    'generate-keys');  # -m G
-
-if (defined ($opts{'h'})) {
-    usage();
-    exit;
-}
-
-if (defined($opts{'k'})) {
-    $KEYID = $opts{'k'};
-}
-if (defined($opts{'c'})) {
-    $cfgfile = $opts{'c'};
-}
-if (defined($opts{'d'})) {
-    $datafile = $opts{'d'};
-}
-if (defined($opts{'p'})) {
-    $passphrase = $opts{'p'};
-}
-if (defined($opts{'s'})) {
-    $SIGDIR = $opts{'s'};
-}
-
-if (defined ($opts{'m'}) && ($opts{'m'} =~ /[FfDdREeG]{1}/) ) {
-    $action = $opts{'m'};
-}
-elsif (defined ($opts{'create-cfgfile'})) {
-    $action = 'F';
-}
-elsif (defined ($opts{'print-cfgfile'})) {
-    $action = 'f';
-}
-elsif (defined ($opts{'create-datafile'})) {
-    $action = 'D';
-}
-elsif (defined ($opts{'print-datafile'})) {
-    $action = 'd';
-}
-elsif (defined ($opts{'remove-signature'})) {
-    $action = 'R';
-}
-elsif (defined ($opts{'sign'})) {
-    $action = 'E';
-}
-elsif (defined ($opts{'examine'})) {
-    $action = 'e';
-}
-elsif (defined ($opts{'generate-keys'})) {
-    $action = 'G';
-}
-else {
-    usage();
-    die ("No valid action specified !");
-}
-
-if (defined($ARGV[0])) {
-    $file1 = $ARGV[0];
-} 
-if (defined($ARGV[1])) {
-    $file2 = $ARGV[1];
-} 
-
-
-if (($action =~ /[REe]{1}/) && !defined($file1)) {
-    usage();
-    die("Option -m $action requires a filename (or '-' for stdio)\n");
-}
-
-if ($action =~ /^F$/) {
-    if (!defined($file1)) {
-	$file1 = $cfgfile;
-    }
-    $file2 = $cfgfile;
-    sign_file ();
-}
-
-if ($action =~ /^D$/) {
-    if (!defined($file1)) {
-	$file1 = $datafile;
-    }
-    $file2 = $datafile;
-    sign_file ();
-}
-
-if ($action =~ /^R$/) {
-    # $file1 defined
-    my $i = 0;
-    while (defined($ARGV[$i])) {
-	$file1 = $ARGV[$i];
-	remove ();
-	++$i;
-    }
-}
-
-if ($action =~ /^E$/) {
-    # $file1 defined
-    # default: $file2 = $file1
-    check_signify_sign();
-    my $i = 0;
-    while (defined($ARGV[$i])) {
-	$file1 = $ARGV[$i];
-	$file2 = $file1;
-	$return_from_sign = 1;
-	sign_file ();
-	++$i;
-    }
-}
-
-if ($action =~ /^e$/) {
-    # $file1 defined
-    # default: $file2 = stdout
-    check_signify_verify();
-    my $i = 0;
-    my $ret = 0;
-    while (defined($ARGV[$i])) {
-	print "\n";
-	$file1 = $ARGV[$i];
-	$ret += examine ();
-	++$i;
-	print "\n--------------------------------\n" if (defined($ARGV[$i]));
-    }
-    exit($ret);
-}
-
-if ($action =~ /^f$/) {
-    $file1 = $cfgfile;
-    $file2 = "-";
-    print_cfgfile ();
-}
-
-if ($action =~ /^d$/) {
-    # $file1 irrelevant
-    if (defined($opts{'l'})) {
-	print_datafile ();
-    } else {
-	$file1 = $datafile;
-	$file2 = "-";
-	print_cfgfile ();
-    }
-}
-
-
-
Index: trunk/scripts/samhainadmin.pl.in
===================================================================
--- trunk/scripts/samhainadmin.pl.in	(revision 1)
+++ trunk/scripts/samhainadmin.pl.in	(revision 1)
@@ -0,0 +1,612 @@
+#! /usr/bin/perl
+
+# Copyright Rainer Wichmann (2004)
+#
+# License Information:
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+use warnings;
+use strict;
+use Getopt::Long;
+use File::Basename;
+use File::stat;
+use File::Temp qw/ tempfile tempdir unlink0 /;
+use IO::Handle;
+
+File::Temp->safe_level( File::Temp::HIGH );
+
+my %opts = ();
+my $action;
+my $file1;
+my $file2;
+my $passphrase;
+my $return_from_sign = 0;
+my $no_print_examine = 0;
+my $base = basename($0);
+
+my $cfgfile  = "@myconffile@";
+my $datafile = "@mydatafile@";
+my $daemon   = "@sbindir@/@install_name@";
+my $gpg      = "@mygpg@";
+
+$gpg = "gpg" if ($gpg eq "");
+
+sub usage() {
+    print "Usage:\n";
+    print "  $base { -m F | --create-cfgfile }    [options] [in.cfgfile]\n";
+    print "    Sign the configuration file. If in.cfgfile is given, sign it\n";
+    print "    and install it as configuration file.\n\n";
+
+    print "  $base { -m f | --print-cfgfile }     [options] \n";
+    print "    Print the configuration file to stdout. Signatures are removed.\n\n";
+
+    print "  $base { -m D | --create-datafile }   [options] [in.datafile]\n";
+    print "    Sign the database file. If in.datafile is given, sign it\n";
+    print "    and install it as database file.\n\n";
+
+    print "  $base { -m d | --print-datafile }    [options] \n";
+    print "    Print the database file to stdout. Signatures are removed. Use\n";
+    print "    option --list to list files in database rather than printing the raw file.\n\n";
+
+    print "  $base { -m R | --remove-signature }  [options] file1 [file2 ...]\n";
+    print "    Remove cleartext signature from input file(s). The file\n";
+    print "    is replaced by the non-signed file.\n\n";
+
+    print "  $base { -m E | --sign }              [options] file1 [file2 ...]\n";
+    print "    Sign file(s) with a cleartext signature. The file\n";
+    print "    is replaced by the signed file.\n\n";
+
+    print "  $base { -m e | --examine }           [options] file1 [file2 ...]\n";
+    print "    Report signature status of file(s).\n\n";
+
+    print "  $base { -m G | --generate-keys }     [options] \n";
+    print "    Generate a PGP keypair to use for signing.\n\n";
+
+    print "Options:\n";
+    print "  -c cfgfile    --cfgfile cfgfile\n";
+    print "    Select an alternate configuration file.\n\n";
+
+    print "  -d datafile   --datafile datafile\n";
+    print "    Select an alternate database file.\n\n";
+
+    print "  -p passphrase --passphrase passphrase\n";
+    print "    Set the passphrase for gpg. By default, gpg will ask.\n\n";
+
+    print "  -l            --list\n";
+    print "    List the files in database rather than printing the raw file.\n\n";
+
+    print "  -v            --verbose\n";
+    print "    Verbose output.\n\n";
+    return;
+}
+
+sub check_gpg_uid () {
+    if (0 != $>) {
+	print "--------------------------------------------------\n";
+	print "\n";
+	print " You are not root. Please remember that samhain/yule\n";
+	print " will use the public keyring of root to verify a signature.\n";
+	print "\n";
+	print "--------------------------------------------------\n";
+    } else {
+	if (!("@yulectl_prg@" =~ //)) {
+	    print "--------------------------------------------------\n";
+	    print "\n";
+	    print " Please remember that yule will drop root after startup. Signature\n";
+	    print " verification on SIGHUP will fail if you do not import the public key\n";
+	    print " into the keyring of the non-root yule user.\n";
+	    print "\n";
+	    print "--------------------------------------------------\n";
+	}
+    }
+}
+    
+sub check_gpg_sign () {
+    if ( (!-d "$ENV{'HOME'}/.gnupg") || (!-e "$ENV{'HOME'}/.gnupg/secring.gpg")) {
+	print "--------------------------------------------------\n";
+	print "\n";
+	if (!-d "$ENV{'HOME'}/.gnupg") {
+	    print " Directory \$HOME/.gnupg not found!\n";
+	} else {
+	    print " Secret keyring \$HOME/.gnupg/secring.gpg not found!\n";
+	}
+	print "\n";
+	print " This indicates that you have never created a \n";
+	print " public/private keypair, and thus cannot sign.\n";
+	print " \n";
+	print " Please use $0 --generate-keys or gpg --gen-key\n";
+	print " to generate a public/private keypair first.\n";
+	print "\n";
+	print "--------------------------------------------------\n";
+	print "\n";
+	exit;
+    }
+}
+
+sub check_gpg_verify () {
+    if ( (!-d "$ENV{'HOME'}/.gnupg") || (!-e "$ENV{'HOME'}/.gnupg/pubring.gpg")) {
+	print "--------------------------------------------------\n";
+	print "\n";
+	if (!-d "$ENV{'HOME'}/.gnupg") {
+	    print " Directory \$HOME/.gnupg not found!\n";
+	} else {
+	    print " Public keyring \$HOME/.gnupg/pubring.gpg not found!\n";
+	}
+	print "\n";
+	print " This indicates that you have never used gpg before \n";
+	print " and/or have no public keys to verify signatures.\n";
+	print " \n";
+	print " Please use 'gpg --export key_id' to export the public\n";
+	print " signing key of the user who is signing the\n";
+	print " configuration/database files.\n\n";
+	print " Then you can use 'gpg --import keyfile' to import the key\n";
+	print " into this user's public keyring.\n";
+	print "\n";
+	print "--------------------------------------------------\n";
+	print "\n";
+	exit;
+    }
+}
+
+
+sub generate () {
+    my $command = "$gpg --homedir $ENV{'HOME'}/.gnupg --gen-key";
+    check_gpg_uid();
+    system ($command) == 0 
+	or die "system $command failed: $?";
+    exit;
+}
+
+sub examine () {
+    my $iscfg = 0;
+    my $have_fp  = 0;
+    my $have_sig = 0;
+    my $message = '';
+    my $retval  = 9;
+    my $fh;
+    my $filename;
+
+    if (!($file1 =~ /^\-$/)) {
+	die ("Cannot open $file1 for read: $!") unless ((-e $file1) && (-r _));
+    }
+    open FIN,  "<$file1" or die "Cannot open $file1 for read: $!";
+
+    my $dir = tempdir( CLEANUP => 1 );
+    $filename = $dir . "/exa_jhfdbilw";
+    open $fh, ">$filename" or die "Cannot open $filename";
+    autoflush $fh 1;
+
+    while (<FIN>) {
+	print $fh $_;
+	if ($_ =~ /^\s*\[Misc\]/) {
+	    $iscfg = 1;
+	}
+    }
+    if ($iscfg == 1) {
+	$message .=  "File $file1 is a configuration file\n\n";
+    } else {
+	$message .=  "File $file1 is a database file\n\n";
+    }
+
+
+    my $command = "$gpg --homedir $ENV{'HOME'}/.gnupg --status-fd 1 ";
+    $command .= "--verbose " if (defined($opts{'v'}));
+    $command .= "--verify $filename ";
+    if (defined($opts{'v'})) {
+	$command .= "2>&1";
+    } else {
+	$command .= "2>/dev/null";
+    }
+
+    print STDOUT "Using: $command\n\n" if (defined($opts{'v'}));
+    open  GPGIN, "$command |" or die "Cannot fork: $!";
+
+    while (<GPGIN>) {
+	if ($_ =~ /^\[GNUPG:\] GOODSIG ([0-9A-F]+) (.*)$/) {
+	    $message .= "GOOD signature with key: $1\n";
+	    $message .= "Key owner:               $2\n";
+	    $have_sig = 1;
+	    $retval   = 0;
+	}
+	if ($_ =~ /^\[GNUPG:\] VALIDSIG ([0-9A-F]+) ([0-9\-]+)\s/) {
+	    $message .= "Key fingerprint:         $1\n";
+	    $message .= "Signature generated on:  $2\n\n";
+	    $have_fp = 1;
+	    $message .=  "This file is signed with a valid signature.\n" 
+		if ($have_sig == 1);
+	    $have_sig = 1;
+	    $have_fp = 1;
+	}
+	if ($_ =~ /^\[GNUPG:\] NODATA 1/) {
+	    $message .=  "NO signature found.\n\n";
+	    $message .=  "This file is not signed !!!\n";
+	    $have_sig = 1;
+	    $have_fp = 1;
+	    $retval  = 2;
+	}
+	if ($_ =~ /^\[GNUPG:\] BADSIG ([0-9A-F]+) (.*)$/) {
+	    $message .=  "BAD signature with key: $1\n";
+	    $message .=  "Key owner:              $2\n\n";
+	    $message .=  "This file is signed with an invalid signature !!!\n";
+	    $have_sig = 1;
+	    $have_fp = 1;
+	    $retval = 1;
+	}
+	if ($_ =~ /^\[GNUPG:\] NO_PUBKEY ([0-9A-F]+)/) {
+	    $message .=  "NOT CHECKED signature with key: $1\n\n";
+	    $message .=  "The signature of this file cannot be checked: no public key available !!!\n";
+	    $have_sig = 1;
+	    $have_fp = 1;
+	    $retval  = 1;
+	}
+	print STDOUT $_ if (defined($opts{'v'}));
+    }
+    close (GPGIN);
+    print STDOUT "\n" if (defined($opts{'v'}));
+    if ($have_sig == 0) {
+	$message .=  "NO valid signature found\n";
+    } 
+    elsif ($have_fp == 0) {
+	$message .=  "NO fingerprint found\n";
+    }
+    close (FIN);
+    if ($no_print_examine == 0) {
+	print STDOUT $message;
+    }
+    unlink0( $fh, $filename ) or die "Cannot unlink $filename safely";
+    return $retval;
+}
+
+sub remove () {
+    my $bodystart = 1;
+    my $sigstart  = 0;
+    my $sigend    = 0;
+    my $filename  = "";
+    my $fh;
+    my $stats;
+
+    open FH, "<$file1" or die "Cannot open file $file1 for read: $!";
+    if (!($file1 =~ /^\-$/)) {
+	my $dir = tempdir( CLEANUP => 1 ) or die "Tempdir failed";
+	$filename = $dir . "/rem_iqegBCQb";
+	open $fh, ">$filename" or die "Cannot open $filename";
+	$stats = stat($file1);
+	# ($fh, $filename) = tempfile(UNLINK => 1);
+    } else {
+	open $fh, ">$file1" or die "Cannot open file $file1 for write: $!";
+    }
+    autoflush $fh 1;
+    while (<FH>) {
+	if ($_ =~ /^-----BEGIN PGP SIGNED MESSAGE-----/) {
+	    $sigstart = 1;
+	    $bodystart = 0;
+	    next;
+	} elsif (($sigstart == 1) && ($_ =~ /^\s+$/)) {
+	    $sigstart = 0;
+	    $bodystart = 1;
+	    next;
+	} elsif ($_ =~ /^-----BEGIN PGP SIGNATURE-----/) {
+	    $bodystart = 0;
+	    $sigend = 1;
+	    next;
+	} elsif (($sigend == 1) && ($_ =~ /^-----END PGP SIGNATURE-----/)) {
+	    $sigend = 0;
+	    $bodystart = 1;
+	    next;
+	}
+	if ($bodystart == 1) {
+	    print $fh $_;
+	}
+    }
+    if (!($file1 =~ /^\-$/)) {
+	my $command = "cp $filename $file1";
+	system ($command) == 0
+	    or die "system $command failed: $?";
+	chmod $stats->mode, $file1;
+	chown $stats->uid, $stats->gid, $file1;
+    }
+    unlink0( $fh, $filename ) or die "Cannot unlink $filename safely";
+    return;
+}
+
+sub print_cfgfile () {
+    my $bodystart = 0;
+    my $sigstart  = 0;
+
+    if (!defined($file2)) {
+	$file2 = '-';
+    }
+
+    open FH, "<$file1" or die "Cannot open file $file1 for read: $!";
+    open FO, ">$file2" or die "Cannot open file $file2 for write: $!";
+    while (<FH>) {
+	if ($_ =~ /^-----BEGIN PGP SIGNED MESSAGE-----/) {
+	    $sigstart = 1;
+	    next;
+	} elsif (($sigstart == 1) && ($_ =~ /^\s+$/)) {
+	    $sigstart = 0;
+	    $bodystart = 1;
+	    next;
+	} elsif ($_ =~ /^-----BEGIN PGP SIGNATURE-----/) {
+	    $bodystart = 0;
+	    exit;
+	}
+	if ($bodystart == 1) {
+	    print FO $_;
+	}
+    }
+    exit;
+}
+sub print_datafile () {
+    die ("Cannot find program $daemon") 
+	unless (-e $daemon);
+    if (defined($opts{'v'})) {
+	open FH, "$daemon --full-detail -d $datafile |" 
+	    or die "Cannot open datafile $datafile for read: $!";
+    } else {
+	open FH, "$daemon -d $datafile |" 
+	    or die "Cannot open datafile $datafile for read: $!";
+    }
+    while (<FH>) {
+	print $_;
+    }
+    exit;
+}
+
+sub sign_file () {
+
+    my $fileout = '';
+    my $bodystart = 1;
+    my $sigstart  = 0;
+    my $sigend    = 0;
+    my $stats;
+    my $fh1;
+    my $filename1;
+    my $flag1     = 0;
+
+    check_gpg_uid();
+
+    if (!defined($file2)) {
+	$file2 = $file1;
+    }
+
+    if ($file1 =~ /^\-$/) {
+	my $dir = tempdir( CLEANUP => 1 ) or die "Tempdir failed";
+	$filename1 = $dir . "/sig_vs8827sd";
+	open $fh1, ">$filename1" or die "Cannot open $filename1";
+	$flag1 = 1;
+	# my ($fh1, $filename1) = tempfile(UNLINK => 1);
+
+	while (<STDIN>) {
+	  if ($_ =~ /^-----BEGIN PGP SIGNED MESSAGE-----/) {
+	    $sigstart = 1;
+	    $bodystart = 0;
+	    next;
+	  } elsif (($sigstart == 1) && ($_ =~ /^\s+$/)) {
+	    $sigstart = 0;
+	    $bodystart = 1;
+	    next;
+	  } elsif ($_ =~ /^-----BEGIN PGP SIGNATURE-----/) {
+	    $bodystart = 0;
+	    $sigend = 1;
+	    next;
+	  } elsif (($sigend == 1) && ($_ =~ /^-----END PGP SIGNATURE-----/)) {
+	    $sigend = 0;
+	    $bodystart = 1;
+	    next;
+	  }
+	  if ($bodystart == 1) {
+	    print $fh1 $_;
+	  }
+	  #
+	  # print $fh1 $_;
+	  #
+	}
+	$file1 = $filename1;
+	$fileout = '-';
+    } else {
+	$no_print_examine = 1;
+	if (examine() < 2) {
+	    remove();
+	}
+	$fileout = $file1 . ".asc";
+	$stats   = stat($file1);
+    }
+
+    if (defined($passphrase)) {
+	local $SIG{PIPE} = 'IGNORE';
+	my $command = "$gpg --homedir $ENV{'HOME'}/.gnupg --passphrase-fd 0 -a --clearsign -o $fileout --not-dash-escaped $file1";
+	open (FH, "|$command")  or die "can't fork: $!";
+	print FH "$passphrase"  or die "can't write: $!";
+	close FH                or die "can't close: status=$?";
+    } else {
+	my $command = "$gpg --homedir $ENV{'HOME'}/.gnupg                   -a --clearsign -o $fileout --not-dash-escaped $file1";
+	system("$command") == 0 
+	    or die "system $command failed: $?";
+    }
+
+    if (!($fileout =~ /^\-$/)) {
+	my $st_old = stat($file1) 
+	    or die "No file $file1: $!";
+	my $st_new = stat($fileout) 
+	    or die "No file $fileout: $!";
+	die ("Signed file is smaller than unsigned file") 
+	    unless ($st_new->size > $st_old->size);
+	system ("mv $fileout $file2") == 0
+	    or die "system mv $fileout $file2 failed: $?";
+	chmod $stats->mode, $file2;
+	chown $stats->uid, $stats->gid, $file2;
+    }
+
+    if ($flag1 == 1) {
+	unlink0( $fh1, $filename1 ) or die "Cannot unlink $filename1 safely";
+    }
+    if ($return_from_sign == 1) {
+	return;
+    }
+    exit;
+}
+
+Getopt::Long::Configure ("posix_default");
+Getopt::Long::Configure ("bundling");
+# Getopt::Long::Configure ("debug");
+
+GetOptions (\%opts, 'm=s', 'h|help', 'v|verbose', 'l|list',
+	    'c|cfgfile=s',
+	    'd|datafile=s',
+	    'p|passphrase=s',
+	    'create-cfgfile',  # -m F
+	    'print-cfgfile',   # -m f
+	    'create-datafile', # -m D
+	    'print-datafile',  # -m d
+	    'remove-signature',# -m R
+	    'sign',            # -m E
+	    'examine',         # -m e
+	    'generate-keys');  # -m G
+
+if (defined ($opts{'h'})) {
+    usage();
+    exit;
+}
+
+if (defined($opts{'c'})) {
+    $cfgfile = $opts{'c'};
+}
+if (defined($opts{'d'})) {
+    $datafile = $opts{'d'};
+}
+if (defined($opts{'p'})) {
+    $passphrase = $opts{'p'};
+}
+
+if (defined ($opts{'m'}) && ($opts{'m'} =~ /[FfDdREeG]{1}/) ) {
+    $action = $opts{'m'};
+}
+elsif (defined ($opts{'create-cfgfile'})) {
+    $action = 'F';
+}
+elsif (defined ($opts{'print-cfgfile'})) {
+    $action = 'f';
+}
+elsif (defined ($opts{'create-cfgfile'})) {
+    $action = 'D';
+}
+elsif (defined ($opts{'print-cfgfile'})) {
+    $action = 'd';
+}
+elsif (defined ($opts{'remove-signature'})) {
+    $action = 'R';
+}
+elsif (defined ($opts{'sign'})) {
+    $action = 'E';
+}
+elsif (defined ($opts{'examine'})) {
+    $action = 'e';
+}
+elsif (defined ($opts{'generate-keys'})) {
+    $action = 'G';
+}
+else {
+    usage();
+    die ("No valid action specified !");
+}
+
+if (defined($ARGV[0])) {
+    $file1 = $ARGV[0];
+} 
+if (defined($ARGV[1])) {
+    $file2 = $ARGV[1];
+} 
+
+
+if (($action =~ /[REe]{1}/) && !defined($file1)) {
+    usage();
+    die("Option -m $action requires a filename (or '-' for stdio)\n");
+}
+
+if ($action =~ /^F$/) {
+    if (!defined($file1)) {
+	$file1 = $cfgfile;
+    }
+    $file2 = $cfgfile;
+    sign_file ();
+}
+
+if ($action =~ /^D$/) {
+    if (!defined($file1)) {
+	$file1 = $datafile;
+    }
+    $file2 = $datafile;
+    sign_file ();
+}
+
+if ($action =~ /^R$/) {
+    # $file1 defined
+    my $i = 0;
+    while (defined($ARGV[$i])) {
+	$file1 = $ARGV[$i];
+	remove ();
+	++$i;
+    }
+}
+
+if ($action =~ /^E$/) {
+    # $file1 defined
+    # default: $file2 = $file1
+    check_gpg_sign();
+    my $i = 0;
+    while (defined($ARGV[$i])) {
+	$file1 = $ARGV[$i];
+	$file2 = $file1;
+	$return_from_sign = 1;
+	sign_file ();
+	++$i;
+    }
+}
+
+if ($action =~ /^e$/) {
+    # $file1 defined
+    # default: $file2 = stdout
+    check_gpg_verify();
+    my $i = 0;
+    while (defined($ARGV[$i])) {
+	print "\n";
+	$file1 = $ARGV[$i];
+	examine ();
+	++$i;
+	print "\n--------------------------------\n" if (defined($ARGV[$i]));
+    }
+}
+
+if ($action =~ /^f$/) {
+    $file1 = $cfgfile;
+    $file2 = "-";
+    print_cfgfile ();
+}
+
+if ($action =~ /^d$/) {
+    # $file1 irrelevant
+    if (defined($opts{'l'})) {
+	print_datafile ();
+    } else {
+	$file1 = $datafile;
+	$file2 = "-";
+	print_cfgfile ();
+    }
+}
+
+
+
Index: trunk/scripts/samhainrc_update.sh
===================================================================
--- trunk/scripts/samhainrc_update.sh	(revision 1)
+++ trunk/scripts/samhainrc_update.sh	(revision 1)
@@ -0,0 +1,227 @@
+#!/bin/bash
+# ----------------------------------------------------------------------------- 
+# @brief: update the kernel options in the samhain configuration
+#         file, after a new kernel has been compiled
+# @author: marc heisterkamp <marzheister@web.de>
+# ----------------------------------------------------------------------------- 
+
+SAMHAIN_CFG="/etc/samhainrc"
+
+BLUE="[34;01m"
+CYAN="[36;01m"
+GREEN="[32;01m"
+DARK_GREEN="[32m"
+RED="[31;01m"
+PURPLE="[35;01m"
+WHITE="[37;01m"
+DARK_GRAY="[30;01m"
+LIGHT_GRAY="[37m"
+YELLOW="[33;01m"
+BROWN="[33m"
+OFF="[0m"
+
+
+SYSTEM_MAP=""
+new_cfg=''
+scriptname="$0"
+
+# global variables for system adresses (extracted from System.map)
+SYS_CALL=''
+SYS_CALL_TABLE=''
+PROC_ROOT=''
+PROC_ROOT_IOPS=''
+PROC_ROOT_LOOKUP=''
+
+# Make sure the user has root permissions
+if [ $UID -ne 0 ] ; then
+  echo "You must be root to run this script. Exiting."
+  exit 1
+fi
+
+
+#------------------------------------------------------------------------------
+# usage 
+#------------------------------------------------------------------------------
+function print_usage() {
+
+  cat >&2 <<EOHELP
+
+  update the samhainrc configuration file with new kernel system addresses
+  (i.e: after kernel compilation) by extracting these from the new System.map 
+  file
+
+  SYNOPSIS
+     $scriptname [ ${GREEN}--help${OFF} ]
+                           [ ${GREEN}--nocolor${OFF} ]
+                           [ ${GREEN}--print-only${OFF} ] <System.map>
+                           [ ${GREEN}--update${OFF} ]     <System.map>
+
+  OPTIONS
+     ${GREEN}-h${OFF} ${GREEN}--help${OFF}
+        Show help. 
+
+     ${GREEN}--nocolor${OFF}
+        Disable color hilighting for non ANSI-compatible terms.
+
+     ${GREEN}-p${OFF} ${GREEN}--print-only${OFF} <System.map>
+        Print the extracted system adresses and do not write them to the 
+        samhain configuration file. 
+
+     ${GREEN}-u${OFF} ${GREEN}--update${OFF} <System.map>
+        Update the samhainrc configuration file with new kernel system
+        addresses from the given System.map file 
+
+EOHELP
+ exit 0
+}
+
+
+#------------------------------------------------------------------------------
+# parses the command line options 
+# param in: all parameters given to the script 
+#------------------------------------------------------------------------------
+function parse_cmd_line() {
+
+  # parse the command-line
+  while [ -n "$1" ]; do
+    case "$1" in
+      --help|-h) 
+        print_usage
+        ;;
+      --nocolor|-n)
+        unset DARK_GREEN GREEN RED BROWN LIGHT_GRAY WHITE OFF 
+        ;;
+      --print-only|-p)
+        shift
+        SYSTEM_MAP="$1"
+        get_system_addresses
+        print_system_addresses
+        break
+        ;;
+      --update|-u)
+        shift
+        SYSTEM_MAP="$1"
+        get_system_addresses
+        print_system_addresses
+        replace_system_addresses
+        ;;
+      -*)
+        echo "$scriptname: unknown option $1. Exiting" >&2
+        exit 1
+        ;;
+    esac
+    shift
+  done
+}
+
+
+#------------------------------------------------------------------------------
+# extract system adresses from given System.map file and save to global
+# variables 
+#------------------------------------------------------------------------------
+function get_system_addresses() { 
+
+  if [ -z "$SYSTEM_MAP" ] ; then
+    echo
+    echo "No System.map specified. Exiting" >&2
+    echo
+    exit 1
+  fi
+
+  if [ ! -f "$SYSTEM_MAP" ] ; then
+    echo
+    echo "Could not find System.map: $SYSTEM_MAP. Exiting" >&2
+    echo
+    exit 1
+  fi
+
+  # 1. this is the address of system_call (grep system_call System.map) 
+  #    KernelSystemCall = 0xc0106cf8
+  SYS_CALL="0x`grep system_call $SYSTEM_MAP | cut -d' ' -f1`"
+
+  # 2. this is the address of sys_call_table (grep ' sys_call_table' System.map) 
+  #    KernelSyscallTable = 0xc01efb98
+  SYS_CALL_TABLE="0x`grep sys_call_table $SYSTEM_MAP | cut -d' ' -f1`"
+
+  # 3. this is the address of proc_root (grep ' proc_root$' System.map) 
+  #    KernelProcRoot = 0xc01efb98
+  PROC_ROOT="0x`grep ' proc_root$' $SYSTEM_MAP | cut -d' ' -f1`"
+
+  # 4. this is the address of proc_root_inode_operations 
+  #    (grep proc_root_inode_operations System.map) 
+  #    KernelProcRootIops = 0xc01efb98
+  PROC_ROOT_IOPS="0x`grep proc_root_inode_operations $SYSTEM_MAP | cut -d' ' -f1`"
+
+  # 5. this is the address of proc_root_lookup
+  #    (grep proc_root_lookup System.map) 
+  #    KernelProcRootLookup = 0xc01efb98
+  PROC_ROOT_LOOKUP="0x`grep proc_root_lookup $SYSTEM_MAP | cut -d' ' -f1`"
+}
+
+
+#------------------------------------------------------------------------------
+# extract system adresses from given System.map file and save to global
+# variables 
+#------------------------------------------------------------------------------
+function replace_system_addresses() { 
+
+  if [ -z "$SAMHAIN_CFG" ] ; then
+    echo "Could not find your samhainrc config file: $SAMHAIN_CFG. Exiting" >&2
+    exit 1
+  fi
+
+  echo
+  echo "Replacing current kernel system addresses in: $SAMHAIN_CFG"
+
+  # 1. replace current 'KernelSystemCall' setting
+  new_cfg=`sed -e "s/^\(KernelSystemCall[[:blank:]]*=\)[[:blank:]]*\(.*\)/\1 ${SYS_CALL}/" $SAMHAIN_CFG` 
+
+  # 2. replace current 'KernelSyscallTable' setting
+  new_cfg=`echo "$new_cfg" | sed -e "s/^\(KernelSyscallTable[[:blank:]]*=\)[[:blank:]]*\(.*\)/\1 ${SYS_CALL_TABLE}/"` 
+
+  # 3. replace current 'KernelProcRoot' setting
+  new_cfg=`echo "$new_cfg" | sed -e "s/^\(KernelProcRoot[[:blank:]]*=\)[[:blank:]]*\(.*\)/\1 ${PROC_ROOT}/"` 
+
+  # 4. replace current 'KernelProcRootIops' setting
+  new_cfg=`echo "$new_cfg" | sed -e "s/^\(KernelProcRootIops[[:blank:]]*=\)[[:blank:]]*\(.*\)/\1 ${PROC_ROOT_IOPS}/"` 
+
+  # 5. replace current 'KernelSystemCall' setting
+  new_cfg=`echo "$new_cfg" | sed -e "s/^\(KernelProcRootLookup[[:blank:]]*=\)[[:blank:]]*\(.*\)/\1 ${PROC_ROOT_LOOKUP}/"` 
+
+  echo "Backup old samhainrc $SAMHAIN_CFG to $SAMHAIN_CFG.bak"
+
+  # backup old samhainrc config file 
+  mv "$SAMHAIN_CFG" "$SAMHAIN_CFG.bak"
+
+  # write new samhainrc config file 
+  echo "$new_cfg" > "$SAMHAIN_CFG"
+
+  echo "Successfully updated kernel system addresses."
+  echo
+}
+
+
+#------------------------------------------------------------------------------
+# print samhain required system adresses 
+#------------------------------------------------------------------------------
+function print_system_addresses() {
+
+  echo 
+  echo "your kernel system addresses from: `basename $SYSTEM_MAP`"
+  echo 
+  echo "  KernelSystemCall     = $SYS_CALL"
+  echo "  KernelSyscallTable   = $SYS_CALL_TABLE"
+  echo "  KernelProcRoot       = $PROC_ROOT"
+  echo "  KernelProcRootIops   = $PROC_ROOT_IOPS"
+  echo "  KernelProcRootLookup = $PROC_ROOT_LOOKUP"
+  echo 
+
+}
+
+if [ $# -eq 0 ] ; then
+  print_usage
+fi
+
+parse_cmd_line $*
+
+exit 0
Index: trunk/scripts/yuleadmin.pl.in
===================================================================
--- trunk/scripts/yuleadmin.pl.in	(revision 584)
+++ 	(revision )
@@ -1,303 +1,0 @@
-#! /usr/bin/perl
-
-# Copyright (c) 2007 Riccardo Murri <riccardo.murri@gmail.com>
-#
-# License Information:
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-use warnings;
-use strict;
-use Getopt::Long;
-use File::Basename;
-use File::Copy;
-use File::Temp qw/ tempfile /;
-use IO::File;
-
-# Do I/O to the data file in binary mode (so it 
-# wouldn't complain about invalid UTF-8 characters).
-use bytes;
-
-File::Temp->safe_level( File::Temp::HIGH );
-
-my %opts = ();
-my $outfile;
-my $verbose;
-my $base = basename($0);
-
-my $cfgfile  = "@myconffile@";
-my $yule     = "@sbindir@/@install_name@";
-
-$cfgfile  =~ s/^REQ_FROM_SERVER//;
-
-sub usage() {
-    print <<__END_OF_TEXT__
-Usage:
-  $base { -a | --add } [options] HOSTNAME [PASSWORD]
-    Add client HOSTNAME to configuration file. If PASSWORD is
-    omitted, it is read from stdin.  If HOSTNAME already exists
-    in the configuration file, an error is given.
-
-  $base { -d | --delete } [options] HOSTNAME
-    Remove client HOSTNAME from configuration file.
-
-  $base { -l | --list } [options]
-    List clients in the yule configuration file.
-
-  $base { -r | --replace } [options] HOSTNAME [PASSWORD]
-    Replace password of existing client HOSTNAME in configuration file. 
-    If PASSWORD is omitted, it is read from stdin.  If HOSTNAME does not 
-    already exist in the configuration file, an error is given.
-
-  $base { -u | --update } [options] HOSTNAME [PASSWORD]
-    Add client HOSTNAME to config file or replace its password with a new one.
-    If PASSWORD is omitted, it is read from stdin.  
-
-Options:
-  -c CFGFILE    --cfgfile CFGFILE
-    Select an alternate configuration file. (default: $cfgfile)
-
-  -o OUTFILE    --output OUTFILE
-    Write modified configuration to OUTFILE.  If this option is
-    omitted, $base will rename the original configuration file
-    to '$cfgfile.BAK' and overwrite it with the modified content.
-
-  -Y YULECMD    --yule YULECMD
-    Use command YULECMD to generate the client key from the password.
-    (default: $yule)
-
-  -v            --verbose
-    Verbose output.
-
-__END_OF_TEXT__
-;
-    return;
-}
-
-
-## subroutines
-
-sub read_clients ($) {
-    my $cfgfile = shift || '-';
-    my %clients;
-
-    open INPUT, "<$cfgfile"
-	or die ("Cannot read configuration file '$cfgfile'. Aborting");
-
-    my $section;
-    while (<INPUT>) {
-	# skip comment and blank lines
-	next if m{^\s*#};
-        next if m{^\s*$};
-
-	# match section headers
-	$section = $1 if m{^\s*\[([a-z0-9 ]+)\]}i;
-
-	# ok, list matching lines
-	if ($section =~ m/Clients/) {
-	    if (m{^\s*Client=}i) {
-		chomp;
-		s{^\s*Client=}{}i;
-		my ($client, $key) = split /@/,$_,2;
-
-		$clients{lc($client)} = $key;
-	    }
-	}
-    }
-    
-    close INPUT;
-    return \%clients;
-}
-
-
-sub write_clients ($$$) {
-    my $cfgfile_in = shift || '-';
-    my $cfgfile_out = shift || $cfgfile_in;
-    my $clients = shift;
-
-    my @lines;
-    my $in_clients_section;
-
-    # copy-pass input file
-    my $section = '';
-    open INPUT, "<$cfgfile_in"
-	or die ("Cannot read configuration file '$cfgfile_in'. Aborting");
-    while (<INPUT>) {
-	# match section headers
-	if (m{^\s*\[([a-z0-9 ]+)\]}i) {
-	    if ($in_clients_section and ($section ne $1)) {
-		# exiting [Clients] section, output remaining ones
-		foreach my $hostname (keys %{$clients}) {
-		    push @lines, 
-		        'Client=' . $hostname . '@' 
-			. $clients->{lc($hostname)} . "\n";
-		    delete $clients->{lc($hostname)};
-		}
-	    }
-	    # update section title
-	    $section = $1;
-	    if ($section =~ m/Clients/i) {
-		$in_clients_section = 1;
-	    } else {
-		$in_clients_section = 0;
-	    }
-	}
-
-	# process entries in [Clients] section
-	if ($in_clients_section) {
-	    if (m{^\s*Client=}i) {
-		my ($hostname, undef) = split /@/,$_,2;
-		$hostname =~ s{^\s*Client=}{}i;
-		if (defined($clients->{lc($hostname)})) {
-		    # output (possibly) modified key
-		    $_ = 'Client=' . $hostname . '@' . $clients->{lc($hostname)} . "\n";
-		    delete $clients->{lc($hostname)};
-		}
-		else {
-		    # client deleted, skip this line from output
-		    $_ = '';
-		}
-	    }
-	}
-
-	# copy input to output
-	push @lines, $_;
-    }
-    close INPUT;
-    
-    # if end-of-file reached within [Clients] section, output remaining ones
-    if ($in_clients_section) {
-	foreach my $hostname (keys %{$clients}) {
-	    push @lines, 'Client=' . $hostname . '@' 
-		. $clients->{lc($hostname)} . "\n";
-	}
-    }
-
-    # if necessary, replace input file with output file
-    if ($cfgfile_in eq $cfgfile_out) {
-	copy($cfgfile_in, $cfgfile_in . '.BAK')
-	    or die("Cannot backup config file '$cfgfile_in'. Aborting");
-    }
-    open OUTPUT, ">$cfgfile_out"
-	or die ("Cannot write to file '$cfgfile_out'. Aborting");
-    # overwrite config file line by line
-    foreach my $line (@lines) { print OUTPUT $line; }
-    close OUTPUT;
-}
-
-
-sub new_client_key ($) {
-    my $password = shift;
-    my $yulecmd = shift || $yule;
-
-    my (undef, $key) = split /@/, `$yulecmd -P $password`, 2;
-    chomp $key;
-    return $key;
-}
-
-
-## main
-
-Getopt::Long::Configure ("posix_default");
-Getopt::Long::Configure ("bundling");
-# Getopt::Long::Configure ("debug");
-
-GetOptions (\%opts, 
-	    'Y|yule=s',
-	    'a|add',
-	    'c|cfgfile=s',
-	    'd|delete',
-	    'h|help', 
-	    'l|list',
-	    'o|output=s',
-	    'r|replace',
-	    'u|update',
-	    'v|verbose', 
-	    );
-
-if (defined ($opts{'h'})) {
-    usage();
-    exit;
-}
-
-if (defined($opts{'c'})) {
-    $cfgfile = $opts{'c'};
-    $outfile = $cfgfile unless defined($outfile);
-}
-if (defined($opts{'Y'})) {
-    $yule = $opts{'Y'};
-}
-if (defined($opts{'v'})) {
-    $verbose = 1;
-}
-if (defined($opts{'o'})) {
-    $outfile = $opts{'o'};
-}
-
-if (defined($opts{'l'})) {
-    # list contents
-    my $clients = read_clients($cfgfile);
-    
-    foreach my $client (keys %{$clients}) {
-	print "$client";
-	print " ${$clients}{$client}" if $verbose;
-	print "\n";
-    }
-}
-elsif (defined($opts{'a'}) 
-       or defined($opts{'u'})
-       or defined($opts{'r'})) {
-    # add HOSTNAME
-    my $hostname = $ARGV[0]
-	or die("Actions --add/--replace/--update require at least argument HOSTNAME. Aborting");
-
-    my $password;
-    if (defined($ARGV[1])) {
-	$password = uc($ARGV[1]);
-    } else {
-	$password = uc(<STDIN>);
-	# remove leading and trailing space
-	$password =~ s{\s*}{}g;
-    }
-    # sanity check
-    die ("Argument PASSWORD must be a 16-digit hexadecimal string. Aborting")
-	unless ($password =~ m/[[:xdigit:]]{16}/);
-
-    my $add = defined($opts{'a'});
-    my $replace = defined($opts{'r'});
-
-    my $clients = read_clients($cfgfile);
-    die ("Client '$hostname' already present in config file - cannot add. Aborting")
-	if ($add and defined(${$clients}{$hostname}));
-    die ("Client '$hostname' not already present in config file - cannot replace. Aborting")
-	if ($replace and not defined(${$clients}{$hostname}));
-
-    $clients->{$hostname} = new_client_key($password)
-      or die ("Cannot get key for the given password. Aborting");
-    write_clients($cfgfile, $outfile, $clients);
-}
-elsif (defined($opts{'d'})) {
-    # remove HOSTNAME
-    my $hostname = $ARGV[0]
-	or die("Action --delete requires one argument HOSTNAME. Aborting");
-
-    my $clients = read_clients($cfgfile);
-    delete ${$clients}{$hostname};
-    write_clients($cfgfile, $outfile, $clients);
-}
-else {
-    usage();
-    die ("You must specify one of --list, --add or --remove options. Aborting");
-}
