Index: /trunk/Makefile.in
===================================================================
--- /trunk/Makefile.in	(revision 549)
+++ /trunk/Makefile.in	(revision 550)
@@ -118,5 +118,5 @@
 	sh_mem.h sh_entropy.h sh_xfer.h sh_modules.h sh_utmp.h \
 	sh_suidchk.h sh_srp.h sh_fifo.h sh_html.h sh_tools.h \
-	sh_gpg.h sh_cat.h sh_calls.h sh_extern.h sh_database.h sh_trace.h \
+	sh_sig.h sh_cat.h sh_calls.h sh_extern.h sh_database.h sh_trace.h \
 	sh_schedule.h bignum.h trustfile.h slib.h zAVLTree.h \
 	lzoconf.h minilzo.h rijndael-alg-fst.h rijndael-api-fst.h \
@@ -144,5 +144,5 @@
 	$(srcsrc)/sh_suidchk.c $(srcsrc)/sh_srp.c \
 	$(srcsrc)/sh_fifo.c $(srcsrc)/sh_tools.c \
-	$(srcsrc)/sh_html.c $(srcsrc)/sh_gpg.c \
+	$(srcsrc)/sh_html.c $(srcsrc)/sh_sig.c \
 	$(srcsrc)/sh_cat.c $(srcsrc)/sh_calls.c \
 	$(srcsrc)/sh_extern.c $(srcsrc)/sh_database.c \
@@ -184,5 +184,5 @@
 	sh_entropy.o sh_modules.o sh_utmp.o \
 	sh_xfer_client.o sh_xfer_server.o sh_xfer_syslog.o \
-	sh_suidchk.o sh_srp.o sh_fifo.o sh_tools.o sh_html.o sh_gpg.o \
+	sh_suidchk.o sh_srp.o sh_fifo.o sh_tools.o sh_html.o sh_sig.o \
 	sh_cat.o sh_calls.o sh_extern.o sh_database.o sh_err_log.o \
 	sh_err_console.o sh_err_syslog.o sh_schedule.o bignum.o \
@@ -205,7 +205,11 @@
 	testtimesrv.sh \
 	testext.sh testrc_1ext.in test_ext.c.in testrun_1d.sh \
-	testrun_1.sh testrun_1a.sh testrun_1b.sh testrun_1c.sh testrc_1 \
+	testrun_1.sh testrun_1a.sh testrun_1b.sh testrun_1c.sh \
+	testrc_1 testrc_1i.dyn test1i_file.sig test1i_samhain.pub \
+	testrun_1d.sh testrun_1e.sh testrun_1f.sh \
+	testrun_1g.sh testrun_1h.sh testrun_1i.sh \
 	testrun_2.sh testrun_2a.sh testrun_2b.sh testrc_2.in \
-	testrun_2c.sh testrun_2d.sh
+	testrun_2c.sh testrun_2d.sh testrun_2e.sh testrun_2f.sh \
+	testrun_2g.sh
 
 DIST_COMMON =  README COPYING LICENSE samhain.jpg \
@@ -374,11 +378,12 @@
 #
 
-DISTCLEANFILES = Makefile samhain.spec sh_gpg_checksum.h sh_gpg_fp.h \
+DISTCLEANFILES = Makefile samhain.spec sh_sig_checksum.h sh_gpg_fp.h \
 	init/samhain.startLinux init/samhain.startGentoo init/samhain.startSystemd \
 	init/samhain.startLSB init/samhain.startFreeBSD \
 	init/samhain.startSolaris init/samhain.startHPUX \
 	init/samhain.startIRIX init/samhain.startMACOSX \
-	deploy.sh sh_MK.h samhain-install.sh sh_gpg_chksum.h sh_gpg_fp.h \
+	deploy.sh sh_MK.h samhain-install.sh \
 	rules.deb rules.deb-light src/CuTestMain.c \
+	scripts/samhainadmin-sig.pl scripts/samhainadmin-gpg.pl \
 	scripts/samhainadmin.pl scripts/check_samhain.pl \
 	scripts/samhain.ebuild scripts/samhain.ebuild-light \
@@ -1548,4 +1553,5 @@
 
 SCRIPTFILES=redhat_i386.client.spec check_samhain.pl samhainadmin.pl \
+samhainadmin-gpg.pl samhainadmin-sig.pl \
 yuleadmin.pl samhain.ebuild samhain.ebuild-light samhain.spec
 
@@ -1621,5 +1627,6 @@
 
 
-samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_restrict.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_xfer.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h $(srcinc)/sh_sem.h sh_MK.h $(srcinc)/sh_schedule.h 
+
+samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_restrict.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_sig.h $(srcinc)/sh_mem.h $(srcinc)/sh_xfer.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h $(srcinc)/sh_sem.h sh_MK.h $(srcinc)/sh_schedule.h 
 sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_restrict.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_sem.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/zAVLTree.h $(srcinc)/sh_subuid.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
@@ -1627,5 +1634,5 @@
 sh_files.o: $(srcsrc)/sh_files.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_tiger.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/sh_inotify.h $(srcinc)/zAVLTree.h $(srcinc)/sh_dbIO.h $(srcinc)/CuTest.h 
 sh_getopt.o: $(srcsrc)/sh_getopt.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_getopt.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_mail.h $(srcinc)/sh_xfer.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_dbCheck.h $(srcinc)/sh_dbCreate.h $(srcinc)/sh_sem.h $(srcinc)/sh_extern.h 
-sh_readconf.o: $(srcsrc)/sh_readconf.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_xfer.h $(srcinc)/sh_gpg.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_ignore.h $(srcinc)/sh_database.h $(srcinc)/sh_mail.h $(srcinc)/sh_modules.h $(srcinc)/sh_nmail.h $(srcinc)/sh_prelink.h $(srcinc)/sh_prelude.h $(srcinc)/sh_tiger.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_restrict.h $(srcinc)/sh_socket.h 
+sh_readconf.o: $(srcsrc)/sh_readconf.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_xfer.h $(srcinc)/sh_sig.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_ignore.h $(srcinc)/sh_database.h $(srcinc)/sh_mail.h $(srcinc)/sh_modules.h $(srcinc)/sh_nmail.h $(srcinc)/sh_prelink.h $(srcinc)/sh_prelude.h $(srcinc)/sh_tiger.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_restrict.h $(srcinc)/sh_socket.h 
 sh_tiger0.o: $(srcsrc)/sh_tiger0.c Makefile config_xor.h $(srcinc)/sh_tiger.h $(srcinc)/sh_unix.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_pthread.h $(srcinc)/sh_string.h $(srcinc)/sh_checksum.h 
 sh_tiger1.o: $(srcsrc)/sh_tiger1.c Makefile config_xor.h 
@@ -1633,12 +1640,15 @@
 sh_tiger1_64.o: $(srcsrc)/sh_tiger1_64.c Makefile config_xor.h 
 sh_tiger2_64.o: $(srcsrc)/sh_tiger2_64.c Makefile config_xor.h 
-sh_hash.o: $(srcsrc)/sh_hash.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_hash.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_ignore.h $(srcinc)/sh_pthread.h $(srcinc)/sh_xfer.h $(srcinc)/sh_hash.h $(srcinc)/sh_checksum.h 
+sh_hash.o: $(srcsrc)/sh_hash.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_hash.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_sig.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_ignore.h $(srcinc)/sh_pthread.h $(srcinc)/sh_xfer.h $(srcinc)/sh_hash.h $(srcinc)/sh_checksum.h 
 sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
+sh_nmail.o: $(srcsrc)/sh_nmail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mem.h $(srcinc)/sh_mail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_string.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/zAVLTree.h 
 sh_mem.o: $(srcsrc)/sh_mem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_pthread.h 
 sh_entropy.o: $(srcsrc)/sh_entropy.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
-sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
+sh_xfer_client.o: $(srcsrc)/sh_xfer_client.c Makefile config_xor.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_xfer.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h 
+sh_xfer_server.o: $(srcsrc)/sh_xfer_server.c Makefile config_xor.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_xfer.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/sh_guid.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
+sh_xfer_syslog.o: $(srcsrc)/sh_xfer_syslog.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_ipvx.h 
 sh_modules.o: $(srcsrc)/sh_modules.c Makefile config_xor.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utmp.h $(srcinc)/sh_mounts.h $(srcinc)/sh_userfiles.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_portcheck.h $(srcinc)/sh_logmon.h $(srcinc)/sh_registry.h $(srcinc)/sh_fInotify.h 
 sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h $(srcinc)/sh_pthread.h $(srcinc)/sh_inotify.h 
-sh_kern.o: $(srcsrc)/sh_kern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_kern.h sh_ks_xor.h $(srcinc)/sh_unix.h $(srcinc)/sh_hash.h 
+sh_login_track.o: $(srcsrc)/sh_login_track.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_tools.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_error_min.h $(srcinc)/CuTest.h $(srcinc)/CuTest.h 
 sh_suidchk.o: $(srcsrc)/sh_suidchk.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_schedule.h $(srcinc)/sh_calls.h $(srcinc)/zAVLTree.h 
 sh_srp.o: $(srcsrc)/sh_srp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mem.h $(srcinc)/sh_utils.h $(srcinc)/sh_srp.h $(srcinc)/bignum.h $(srcinc)/CuTest.h 
@@ -1646,5 +1656,5 @@
 sh_tools.o: $(srcsrc)/sh_tools.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_error.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/rijndael-api-fst.h $(srcinc)/rijndael-api-fst.h 
 sh_html.o: $(srcsrc)/sh_html.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_xfer.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_html.h $(srcinc)/zAVLTree.h 
-sh_gpg.o: $(srcsrc)/sh_gpg.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_gpg.h 
+sh_sig.o: $(srcsrc)/sh_sig.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_sig.h 
 sh_cat.o: $(srcsrc)/sh_cat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_cat.h 
 sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_sub.h $(srcinc)/sh_utils.h 
@@ -1675,29 +1685,24 @@
 sh_userfiles.o: $(srcsrc)/sh_userfiles.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_modules.h $(srcinc)/sh_userfiles.h $(srcinc)/sh_utils.h $(srcinc)/sh_schedule.h $(srcinc)/sh_error.h $(srcinc)/sh_hash.h $(srcinc)/sh_files.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h 
 sh_prelude.o: $(srcsrc)/sh_prelude.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_error_min.h $(srcinc)/sh_prelude.h $(srcinc)/sh_static.h 
-kern_head.o: $(srcsrc)/kern_head.c Makefile config.h $(srcinc)/kern_head.h $(srcinc)/kern_head.h 
 sh_prelink.o: $(srcsrc)/sh_prelink.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h 
 sh_static.o: $(srcsrc)/sh_static.c Makefile config_xor.h $(srcinc)/sh_pthread.h 
-sh_async.o: $(srcsrc)/sh_async.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h 
+sh_portcheck.o: $(srcsrc)/sh_portcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_mem.h $(srcinc)/sh_calls.h $(srcinc)/sh_utils.h $(srcinc)/sh_modules.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/CuTest.h 
+sh_port2proc.o: $(srcsrc)/sh_port2proc.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error_min.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_ipvx.h 
 sh_processcheck.o: $(srcsrc)/sh_processcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_modules.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
-sh_portcheck.o: $(srcsrc)/sh_portcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_mem.h $(srcinc)/sh_calls.h $(srcinc)/sh_utils.h $(srcinc)/sh_modules.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/CuTest.h 
+sh_filter.o: $(srcsrc)/sh_filter.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_filter.h 
 sh_pthread.o: $(srcsrc)/sh_pthread.c Makefile config_xor.h $(srcinc)/sh_pthread.h $(srcinc)/sh_calls.h $(srcinc)/sh_modules.h 
 sh_string.o: $(srcsrc)/sh_string.c Makefile config_xor.h $(srcinc)/sh_string.h $(srcinc)/sh_mem.h $(srcinc)/CuTest.h 
-dnmalloc.o: $(srcsrc)/dnmalloc.c Makefile config.h 
-t-test1.o: $(srcsrc)/t-test1.c Makefile config.h $(srcinc)/malloc.h 
-sh_port2proc.o: $(srcsrc)/sh_port2proc.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error_min.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_ipvx.h 
 sh_log_parse_syslog.o: $(srcsrc)/sh_log_parse_syslog.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
 sh_log_parse_pacct.o: $(srcsrc)/sh_log_parse_pacct.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
+sh_log_parse_samba.o: $(srcsrc)/sh_log_parse_samba.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
+sh_log_parse_generic.o: $(srcsrc)/sh_log_parse_generic.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
 sh_log_parse_apache.o: $(srcsrc)/sh_log_parse_apache.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
 sh_log_evalrule.o: $(srcsrc)/sh_log_evalrule.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/zAVLTree.h 
-sh_log_check.o: $(srcsrc)/sh_log_check.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h 
-sh_log_parse_samba.o: $(srcsrc)/sh_log_parse_samba.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
-sh_nmail.o: $(srcsrc)/sh_nmail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mem.h $(srcinc)/sh_mail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_string.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/zAVLTree.h 
-sh_filter.o: $(srcsrc)/sh_filter.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_filter.h 
-sh_inotify.o: $(srcsrc)/sh_inotify.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_calls.h $(srcinc)/sh_inotify.h $(srcinc)/sh_mem.h $(srcinc)/sh_utils.h $(srcinc)/slib.h $(srcinc)/zAVLTree.h $(srcinc)/sh_calls.h $(srcinc)/sh_inotify.h $(srcinc)/CuTest.h 
 sh_log_correlate.o: $(srcsrc)/sh_log_correlate.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h 
 sh_log_mark.o: $(srcsrc)/sh_log_mark.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mem.h $(srcinc)/sh_string.h $(srcinc)/sh_error_min.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/zAVLTree.h 
+sh_log_check.o: $(srcsrc)/sh_log_check.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h 
+dnmalloc.o: $(srcsrc)/dnmalloc.c Makefile config.h 
+sh_inotify.o: $(srcsrc)/sh_inotify.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_calls.h $(srcinc)/sh_inotify.h $(srcinc)/sh_mem.h $(srcinc)/sh_utils.h $(srcinc)/slib.h $(srcinc)/zAVLTree.h $(srcinc)/sh_calls.h $(srcinc)/sh_inotify.h $(srcinc)/CuTest.h 
 sh_log_repeat.o: $(srcsrc)/sh_log_repeat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h 
-sh_log_parse_generic.o: $(srcsrc)/sh_log_parse_generic.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
-sh_login_track.o: $(srcsrc)/sh_login_track.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_tools.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_error_min.h $(srcinc)/CuTest.h $(srcinc)/CuTest.h 
 sh_audit.o: $(srcsrc)/sh_audit.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_utils.h 
 sh_registry.o: $(srcsrc)/sh_registry.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_modules.h $(srcinc)/sh_hash.h $(srcinc)/sh_tiger.h 
@@ -1709,11 +1714,8 @@
 sh_checksum.o: $(srcsrc)/sh_checksum.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_checksum.h $(srcinc)/sh_utils.h $(srcinc)/CuTest.h 
 sh_guid.o: $(srcsrc)/sh_guid.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/CuTest.h 
-sh_dbIO.o: $(srcsrc)/sh_dbIO.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_gpg.h $(srcinc)/sh_tiger.h $(srcinc)/sh_xfer.h $(srcinc)/sh_pthread.h $(srcinc)/sh_socket.h $(srcinc)/sh_files.h $(srcinc)/zAVLTree.h 
+sh_sem.o: $(srcsrc)/sh_sem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_sem.h $(srcinc)/sh_error_min.h 
+sh_dbIO.o: $(srcsrc)/sh_dbIO.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_sig.h $(srcinc)/sh_tiger.h $(srcinc)/sh_xfer.h $(srcinc)/sh_pthread.h $(srcinc)/sh_socket.h $(srcinc)/sh_files.h $(srcinc)/zAVLTree.h 
 sh_dbCheck.o: $(srcsrc)/sh_dbCheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_hash.h $(srcinc)/sh_files.h $(srcinc)/sh_tiger.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_pthread.h 
 sh_dbCreate.o: $(srcsrc)/sh_dbCreate.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_hash.h $(srcinc)/sh_files.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_pthread.h $(srcinc)/sh_guid.h 
-sh_xfer_client.o: $(srcsrc)/sh_xfer_client.c Makefile config_xor.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_xfer.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h 
-sh_xfer_server.o: $(srcsrc)/sh_xfer_server.c Makefile config_xor.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_xfer.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/sh_guid.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
-sh_xfer_syslog.o: $(srcsrc)/sh_xfer_syslog.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_ipvx.h 
-sh_xload_client.o: $(srcsrc)/sh_xload_client.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_guid.h 
-sh_sem.o: $(srcsrc)/sh_sem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_sem.h $(srcinc)/sh_error_min.h 
 sh_subuid.o: $(srcsrc)/sh_subuid.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_unix.h 
+t-test1.o: $(srcsrc)/t-test1.c Makefile config.h $(srcinc)/malloc.h 
Index: /trunk/acconfig.h
===================================================================
--- /trunk/acconfig.h	(revision 549)
+++ /trunk/acconfig.h	(revision 550)
@@ -231,10 +231,4 @@
 /* The full path to GnuPG                     */
 #undef DEFAULT_GPG_PATH
-
-/* Define if using the gpg/pgp checksum.      */
-#undef HAVE_GPG_CHECKSUM
-
-/* The tiger checksum of the gpg/pgp binary.  */
-#undef GPG_HASH
 
 /* Define if you want to compile in the       */
Index: /trunk/aclocal.m4
===================================================================
--- /trunk/aclocal.m4	(revision 549)
+++ /trunk/aclocal.m4	(revision 550)
@@ -410,5 +410,5 @@
 DESTDIR=
 SH_ENABLE_OPTS="selinux posix-acl asm ssp db-reload xml-log message-queue login-watch process-check port-check mounts-check logfile-monitor userfiles debug ptrace static network udp nocl stealth micro-stealth install-name identity khide suidcheck base largefile mail external-scripts encrypt srp dnmalloc ipv6 shellexpand suid"
-SH_WITH_OPTS="prelude libprelude-prefix database libwrap cflags libs console altconsole timeserver alttimeserver rnd egd-socket port logserver altlogserver kcheck gpg keyid checksum fp recipient sender trusted tmp-dir config-file log-file pid-file state-dir data-file html-file"
+SH_WITH_OPTS="prelude libprelude-prefix database libwrap cflags libs console altconsole timeserver alttimeserver rnd egd-socket port logserver altlogserver signify pubkey-checksum gpg keyid checksum fp recipient sender trusted tmp-dir config-file log-file pid-file state-dir data-file html-file"
 
 # Installation directory options.
Index: /trunk/config.h.in
===================================================================
--- /trunk/config.h.in	(revision 549)
+++ /trunk/config.h.in	(revision 550)
@@ -232,10 +232,4 @@
 #undef DEFAULT_GPG_PATH
 
-/* Define if using the gpg/pgp checksum.      */
-#undef HAVE_GPG_CHECKSUM
-
-/* The tiger checksum of the gpg/pgp binary.  */
-#undef GPG_HASH
-
 /* Define if you want to compile in the       */
 /* public key fingerprint.                    */
@@ -440,4 +434,7 @@
 #undef AC_APPLE_UNIVERSAL_BUILD
 
+/* Define as path to signing binary */
+#undef DEFAULT_SIG_PATH
+
 /* Debug dnmalloc */
 #undef DNMALLOC_CHECKS
@@ -798,4 +795,10 @@
 #undef HAVE_SETUTENT
 
+/* Define if signing binary checksum available. */
+#undef HAVE_SIG_CHECKSUM
+
+/* Define if signing binary checksum available. */
+#undef HAVE_SIG_KEY_HASH
+
 /* Define if you have SI_USER */
 #undef HAVE_SI_USER
@@ -1034,4 +1037,10 @@
 #undef SH_USE_PROCESSCHECK
 
+/* Define as the signing binary TIGER192 checksum. */
+#undef SIG_HASH
+
+/* Define as the signify public key checksum. */
+#undef SIG_KEY_HASH
+
 /* The size of `char *', as computed by sizeof. */
 #undef SIZEOF_CHAR_P
@@ -1090,4 +1099,10 @@
 /* Define if you want extended attributes support. */
 #undef USE_XATTR
+
+/* Define if signature checking is supported. */
+#undef WITH_SIG
+
+/* Define if using OpenBSD signify for signature checking. */
+#undef WITH_SIGNIFY
 
 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
Index: /trunk/configure.ac
===================================================================
--- /trunk/configure.ac	(revision 549)
+++ /trunk/configure.ac	(revision 550)
@@ -12,5 +12,5 @@
 dnl start
 dnl
-AM_INIT_AUTOMAKE(samhain, 4.3.3)
+AM_INIT_AUTOMAKE(samhain, 4.4.0)
 AC_DEFINE([SAMHAIN], 1, [Application is samhain])
 AC_CANONICAL_HOST
@@ -2220,10 +2220,99 @@
 
 dnl
-dnl  GPG/PGP options
+dnl  Signify/GnuPG options
 dnl 
+
+AC_ARG_WITH(signify,
+        [  --with-signify=PATH 		use OpenBSD signify to verify database/config [[no]]],
+        [
+	if test "x${withval}" != "xno"; then
+	  if test "x${cross_compiling}" = xyes; then
+		mysignify="${withval}"
+	  else
+		if test -f "${withval}"; then
+		  mysignify="${withval}"
+		  mychk0=`gpg --load-extension tiger --print-md TIGER192 ${withval} 2>/dev/null`
+		  if test "x$?" != "x0"; then
+		    mychktest=no
+		    for sam_pre in ./samhain ./yule /usr/local/sbin/samhain /usr/local/bin/samhain /usr/bin/samhain /usr/sbin/samhain /usr/local/sbin/yule /usr/local/bin/yule /usr/bin/yule /usr/sbin/yule; do
+		      if test x"${mychktest}" = xyes
+		      then
+			:
+		      else
+		        if test -f ${sam_pre}
+		        then
+			  echo "use existing ${sam_pre} for signify checksum"
+			  mychk0=`${sam_pre} -H ${withval} 2>/dev/null`
+			  if test "x$?" != "x0"; then
+			    if test "x${nocl_code}" != "x"; then
+			       mychk0=`echo -H ${withval} | ${sam_pre} ${nocl_code} 2>/dev/null`
+			       if test "x$?" != "x0"; then
+			       	  :
+			       else
+			          mychk="${mychk0}"
+				  mychktest=yes
+			       fi 
+			    fi
+			  else
+			    mychk="${mychk0}"
+			    mychktest=yes
+			  fi
+		        fi
+		      fi
+		    done
+		    if test x${mychktest} = xno; then
+		      AC_MSG_WARN([--with-signify: cannot determine TIGER192 checksum of ${withval}])
+		      echo "-------------------------------------------------------------"
+		      echo " I cannot find an existing GnuPG or samhain binary to use."
+		      echo " You can:"
+		      echo "   (a) run make to compile a samhain binary, then repeat"
+		      echo "       ./configure and make"
+		      echo "   (b) ignore the failure. The checksum of the signify binary"
+		      echo "       will not get compiled in, thus allowing an attacker"
+		      echo "       to replace signify with a trojan and subverting the"
+		      echo "       signature verification of configure and database files."
+		      echo
+		      echo " PLEASE IGNORE THIS MESSAGE IF YOU ALSO USE --with-checksum"
+		      echo "-------------------------------------------------------------"
+		    fi
+		  else
+		    mychk="${mychk0}"
+		  fi
+		else
+		  AC_MSG_ERROR([--with-signify: cannot find signify PATH=${withval}])
+		fi
+	  fi
+	  AC_DEFINE([WITH_SIG], 1, [Define if signature checking is supported.])
+	  AC_DEFINE([WITH_SIGNIFY], 1, [Define if using OpenBSD signify for signature checking.])
+	  AC_DEFINE_UNQUOTED([DEFAULT_SIG_PATH], _("${mysignify}"), [Define as path to signing binary])
+	  AC_SUBST(mysignify)
+	fi
+	]
+)
+
+AC_ARG_WITH(pubkey-checksum,
+        [  --with-pubkey-checksum=CHKSUM	compile in TIGER192 checksum of signify public key [[no]]],
+        [
+	if test "x${withval}" != "xno"; then
+		if test "x${withval}" == "xyes"; then
+		   	AC_MSG_ERROR([Option --with-pubkey-checksum=CHKSUM: checksum CHKSUM of signify public key not specified.])
+		else
+			if test "x${withval}" = "x"; then
+				AC_MSG_ERROR([Option --with-checksum=CHKSUM: checksum CHKSUM of the signify public key not specified.])
+			fi
+		fi
+		AC_DEFINE([HAVE_SIG_KEY_HASH], 1, [Define if signing binary checksum available.])
+		AC_DEFINE_UNQUOTED([SIG_KEY_HASH], _("${withval}"), [Define as the signify public key checksum.] )
+	fi
+	]
+)
+
 
 AC_ARG_WITH(gpg,
         [  --with-gpg=PATH 		use GnuPG to verify database/config [[no]]],
         [
+	if test "x${mysignify}" != "x"; then
+	   AC_MSG_ERROR([--with-gpg: already using --with-signify])
+	fi
 	if test "x${withval}" != "xno"; then
 	  if test "x${cross_compiling}" = xyes; then
@@ -2284,6 +2373,7 @@
 		fi
 	  fi
+	  AC_DEFINE([WITH_SIG], 1, [Define if signature checking is supported.])
 	  AC_DEFINE(WITH_GPG)
-	  AC_DEFINE_UNQUOTED(DEFAULT_GPG_PATH, _("${mygpg}") )
+	  AC_DEFINE_UNQUOTED([DEFAULT_SIG_PATH], _("${mygpg}"), [Define as path to signing binary])
 	  AC_SUBST(mygpg)
 	fi
@@ -2312,13 +2402,6 @@
 )
 
-dnl AC_ARG_WITH(pgp,
-dnl        [  --with-pgp=PATH		Use PGP to verify database/config (no).],
-dnl         [myppg="$withval"
-dnl 	AC_DEFINE(WITH_PGP)
-dnl 	AC_DEFINE_UNQUOTED(DEFAULT_PGP_PATH, _("${myppg}") )
-dnl 	])
-
 AC_ARG_WITH(checksum,
-        [  --with-checksum=CHKSUM	compile in gpg/pgp checksum [[yes]]],
+        [  --with-checksum=CHKSUM	compile in checksum of signing binary (e.g. gpg) [[yes]]],
         [
 	if test "x${withval}" != "xno"; then
@@ -2326,5 +2409,5 @@
 			if test "x${mychk}" != "x"; then
 				if test "x${mychk}" != "x${withval}"; then
-					AC_MSG_WARN([--with-checksum: possible gpg CHKSUM problem])
+					AC_MSG_WARN([--with-checksum: possible signing binary CHKSUM problem])
 					AC_MSG_WARN([--with-checksum: CHKSUM=${withval}])
 					AC_MSG_WARN([--with-checksum: autodetected=${mychk}])
@@ -2334,18 +2417,19 @@
 		else
 			if test "x${mychk}" = "x"; then
-				AC_MSG_ERROR([Option --with-checksum=CHKSUM: checksum CHKSUM of the gpg binary not specified.])
+				AC_MSG_ERROR([Option --with-checksum=CHKSUM: checksum CHKSUM of the signing binary not specified.])
 			fi
 		fi
-		AC_DEFINE(HAVE_GPG_CHECKSUM)
-		AC_DEFINE_UNQUOTED(GPG_HASH, _("${mychk}") )
-		echo "${mychk}" | sed 's,.*:,,g' | sed 's, ,,g' | sed 's,\(.\),\1:,g' | awk '{ split($0, arr, ":"); m = length($1)/2; print "#ifndef CHKSUM_H"; print "#define CHKSUM_H"; print "char gpgchk[50];"; for (i=1; i <= m; i++) printf "gpgchk[%d] = %c%s%c;\n", i-1, 39, arr[i], 39; printf "gpgchk[48] = %c%c0%c;\n", 39, 92, 39; print "#endif"; }' > sh_gpg_chksum.h 
+		AC_DEFINE([HAVE_SIG_CHECKSUM], 1, [Define if signing binary checksum available.])
+		AC_DEFINE_UNQUOTED([SIG_HASH], _("${mychk}"), [Define as the signing binary TIGER192 checksum.] )
+		echo "${mychk}" | sed 's,.*:,,g' | sed 's, ,,g' | sed 's,\(.\),\1:,g' | awk '{ split($0, arr, ":"); m = length($1)/2; print "#ifndef CHKSUM_H"; print "#define CHKSUM_H"; print "char sigchk[50];"; for (i=1; i <= m; i++) printf "sigchk[%d] = %c%s%c;\n", i-1, 39, arr[i], 39; printf "sigchk[48] = %c%c0%c;\n", 39, 92, 39; print "#endif"; }' > sh_sig_chksum.h 
 	fi
 	],
 	[
-	if test "x${mygpg}" != "x"; then
+	if test "x${mygpg}" != "x" || test "x${mysignify}" != "x"
+	then
 		if test "x${mychk}" != "x"; then
-			AC_DEFINE(HAVE_GPG_CHECKSUM)
-			AC_DEFINE_UNQUOTED(GPG_HASH, _("${mychk}") )
-			echo "${mychk}" | sed 's,.*:,,g' | sed 's, ,,g' | sed 's,\(.\),\1:,g' | awk '{ split($0, arr, ":"); m = length($1)/2; print "#ifndef CHKSUM_H"; print "#define CHKSUM_H"; print "char gpgchk[50];"; for (i=1; i <= m; i++) printf "gpgchk[%d] = %c%s%c;\n", i-1, 39, arr[i], 39; printf "gpgchk[48] = %c%c0%c;\n", 39, 92, 39; print "#endif"; }' > sh_gpg_chksum.h 
+		   	AC_DEFINE([HAVE_SIG_CHECKSUM], 1, [Define if signing binary checksum available.])
+			AC_DEFINE_UNQUOTED([SIG_HASH], _("${mychk}"), [Define as the signing binary TIGER192 checksum.] )
+			echo "${mychk}" | sed 's,.*:,,g' | sed 's, ,,g' | sed 's,\(.\),\1:,g' | awk '{ split($0, arr, ":"); m = length($1)/2; print "#ifndef CHKSUM_H"; print "#define CHKSUM_H"; print "char sigchk[50];"; for (i=1; i <= m; i++) printf "sigchk[%d] = %c%s%c;\n", i-1, 39, arr[i], 39; printf "sigchk[48] = %c%c0%c;\n", 39, 92, 39; print "#endif"; }' > sh_sig_chksum.h 
 		fi
 	fi
@@ -2710,5 +2794,6 @@
 scripts/samhain.ebuild
 scripts/samhain.ebuild-light
-scripts/samhainadmin.pl
+scripts/samhainadmin-gpg.pl
+scripts/samhainadmin-sig.pl
 scripts/yuleadmin.pl
 scripts/check_samhain.pl
@@ -2718,5 +2803,6 @@
 echo timestamp > stamp-h
 chmod +x samhain-install.sh
-chmod +x scripts/samhainadmin.pl
+chmod +x scripts/samhainadmin-gpg.pl
+chmod +x scripts/samhainadmin-sig.pl
 chmod +x scripts/yuleadmin.pl
 chmod +x scripts/check_samhain.pl
@@ -2725,4 +2811,14 @@
 
 chmod +x deploy.sh
+
+if test "x${mysignify}" != x
+then
+	cp -a scripts/samhainadmin-sig.pl scripts/samhainadmin.pl
+fi 
+if test "x${mygpg}" != x
+then
+	cp -a scripts/samhainadmin-gpg.pl scripts/samhainadmin.pl
+fi 
+
 
 if test "x${cross_compiling}" = xyes
Index: /trunk/depend.dep
===================================================================
--- /trunk/depend.dep	(revision 549)
+++ /trunk/depend.dep	(revision 550)
@@ -1,5 +1,5 @@
 
 # DO NOT DELETE THIS LINE
-samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_restrict.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_xfer.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h $(srcinc)/sh_sem.h sh_MK.h $(srcinc)/sh_schedule.h 
+samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_restrict.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_sig.h $(srcinc)/sh_mem.h $(srcinc)/sh_xfer.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h $(srcinc)/sh_sem.h sh_MK.h $(srcinc)/sh_schedule.h 
 sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_restrict.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_sem.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/zAVLTree.h $(srcinc)/sh_subuid.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
@@ -7,5 +7,5 @@
 sh_files.o: $(srcsrc)/sh_files.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_tiger.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/sh_inotify.h $(srcinc)/zAVLTree.h $(srcinc)/sh_dbIO.h $(srcinc)/CuTest.h 
 sh_getopt.o: $(srcsrc)/sh_getopt.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_getopt.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_mail.h $(srcinc)/sh_xfer.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_dbCheck.h $(srcinc)/sh_dbCreate.h $(srcinc)/sh_sem.h $(srcinc)/sh_extern.h 
-sh_readconf.o: $(srcsrc)/sh_readconf.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_xfer.h $(srcinc)/sh_gpg.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_ignore.h $(srcinc)/sh_database.h $(srcinc)/sh_mail.h $(srcinc)/sh_modules.h $(srcinc)/sh_nmail.h $(srcinc)/sh_prelink.h $(srcinc)/sh_prelude.h $(srcinc)/sh_tiger.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_restrict.h $(srcinc)/sh_socket.h 
+sh_readconf.o: $(srcsrc)/sh_readconf.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_xfer.h $(srcinc)/sh_sig.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_ignore.h $(srcinc)/sh_database.h $(srcinc)/sh_mail.h $(srcinc)/sh_modules.h $(srcinc)/sh_nmail.h $(srcinc)/sh_prelink.h $(srcinc)/sh_prelude.h $(srcinc)/sh_tiger.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_restrict.h $(srcinc)/sh_socket.h 
 sh_tiger0.o: $(srcsrc)/sh_tiger0.c Makefile config_xor.h $(srcinc)/sh_tiger.h $(srcinc)/sh_unix.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_pthread.h $(srcinc)/sh_string.h $(srcinc)/sh_checksum.h 
 sh_tiger1.o: $(srcsrc)/sh_tiger1.c Makefile config_xor.h 
@@ -13,5 +13,5 @@
 sh_tiger1_64.o: $(srcsrc)/sh_tiger1_64.c Makefile config_xor.h 
 sh_tiger2_64.o: $(srcsrc)/sh_tiger2_64.c Makefile config_xor.h 
-sh_hash.o: $(srcsrc)/sh_hash.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_hash.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_ignore.h $(srcinc)/sh_pthread.h $(srcinc)/sh_xfer.h $(srcinc)/sh_hash.h $(srcinc)/sh_checksum.h 
+sh_hash.o: $(srcsrc)/sh_hash.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_hash.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_sig.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_ignore.h $(srcinc)/sh_pthread.h $(srcinc)/sh_xfer.h $(srcinc)/sh_hash.h $(srcinc)/sh_checksum.h 
 sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
 sh_mem.o: $(srcsrc)/sh_mem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_pthread.h 
@@ -92,5 +92,5 @@
 sh_checksum.o: $(srcsrc)/sh_checksum.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_checksum.h $(srcinc)/sh_utils.h $(srcinc)/CuTest.h 
 sh_guid.o: $(srcsrc)/sh_guid.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/CuTest.h 
-sh_dbIO.o: $(srcsrc)/sh_dbIO.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_gpg.h $(srcinc)/sh_tiger.h $(srcinc)/sh_xfer.h $(srcinc)/sh_pthread.h $(srcinc)/sh_socket.h $(srcinc)/sh_files.h $(srcinc)/zAVLTree.h 
+sh_dbIO.o: $(srcsrc)/sh_dbIO.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_hash.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_sig.h $(srcinc)/sh_tiger.h $(srcinc)/sh_xfer.h $(srcinc)/sh_pthread.h $(srcinc)/sh_socket.h $(srcinc)/sh_files.h $(srcinc)/zAVLTree.h 
 sh_dbCheck.o: $(srcsrc)/sh_dbCheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_hash.h $(srcinc)/sh_files.h $(srcinc)/sh_tiger.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_pthread.h 
 sh_dbCreate.o: $(srcsrc)/sh_dbCreate.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_hash.h $(srcinc)/sh_files.h $(srcinc)/sh_dbIO.h $(srcinc)/sh_dbIO_int.h $(srcinc)/sh_pthread.h $(srcinc)/sh_guid.h 
@@ -101,2 +101,3 @@
 sh_sem.o: $(srcsrc)/sh_sem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_sem.h $(srcinc)/sh_error_min.h 
 sh_subuid.o: $(srcsrc)/sh_subuid.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_unix.h 
+sh_sig.o: $(srcsrc)/sh_sig.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_sig.h 
Index: /trunk/depend.sum
===================================================================
--- /trunk/depend.sum	(revision 549)
+++ /trunk/depend.sum	(revision 550)
@@ -1,1 +1,1 @@
-3024561571
+3600310821
Index: /trunk/docs/Changelog
===================================================================
--- /trunk/docs/Changelog	(revision 549)
+++ /trunk/docs/Changelog	(revision 550)
@@ -1,6 +1,9 @@
+4.4.0:
+	* support for OpenBSD signify as alternative to GnuPG
+
 4.3.3:
 	* fix broken 'make deb' makefile target
 	* eliminate obsolete 'sstrip' utility
-	* systemd support 
+	* systemd support
 	* fix broken rpm specfile (patch by Franky Van L.)
 	* fix broken mysql init script
@@ -52,5 +55,5 @@
 	* fix build issue with musl libc (report & patch by A. Kuster)
 	* fix case sensitivity (tcp vs TCP, udp vs UDP) in portcheck
-	directives (reported by Anton H.)
+	directives (reported by A. Hofland)
 	* fix documentation typo ('make deploy-install' ->
 	'make install-deploy', reported by Ben)
@@ -72,8 +75,8 @@
 	as uint16, e.g. FreeBSD).
 	* add portcheck option 'PortCheckDevice = device' to monitor a
-	device regardless of address assigned to it (patch by Anton H., plus
+	device regardless of address assigned to it (patch by A. Hofland, plus
 	some additions)
 	* fix case sensitivity of severity/class options (issue raised by
-	Anton H.).
+	A. Hofland).
 	* clarify restrictions for ProcessCheckPSArg (user manual)
 
Index: /trunk/include/sh_calls.h
===================================================================
--- /trunk/include/sh_calls.h	(revision 549)
+++ /trunk/include/sh_calls.h	(revision 550)
@@ -76,6 +76,6 @@
 long int retry_aud_dup2    (const char * file, int line, int fd, int fd2);
 long int retry_aud_execve  (const char * file, int line, 
-			    const  char *dateiname, char * argv[],
-			    char *envp[]);
+			    const  char *dateiname, char *const argv[],
+			    char *const envp[]);
 long int retry_aud_dup     (const char * file, int line, 
 			    int fd);
Index: unk/include/sh_gpg.h
===================================================================
--- /trunk/include/sh_gpg.h	(revision 549)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/* SAMHAIN file system integrity testing                                   */
-/* Copyright (C) 1999 Rainer Wichmann                                      */
-/*                                                                         */
-/*  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.              */
-
-#if (defined(WITH_GPG) || defined(WITH_PGP))
-
-#ifndef SH_GPG_H
-#define SH_GPG_H
-
-#define SIG_CONF 1
-#define SIG_DATA 2
-
-/* Top level function to verify file.
- */
-SL_TICKET sh_gpg_extract_signed(SL_TICKET fd);
-
-/* this function exits if configuration file
- * and/or database cannot be verified; otherwise returns 0
- */
-int sh_gpg_check_sign (long file, int what);
-
-/* log successful startup
- */
-void sh_gpg_log_startup (void);
-
-#endif
-
-/* #ifdef WITH_GPG */
-#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Index: unk/include/sh_gpg_chksum.h
===================================================================
--- /trunk/include/sh_gpg_chksum.h	(revision 549)
+++ 	(revision )
@@ -1,53 +1,0 @@
-#ifndef CHKSUM_H
-#define CHKSUM_H
-char gpgchk[50];
-gpgchk[0] = '4';
-gpgchk[1] = '0';
-gpgchk[2] = '7';
-gpgchk[3] = '8';
-gpgchk[4] = '4';
-gpgchk[5] = '6';
-gpgchk[6] = '0';
-gpgchk[7] = '1';
-gpgchk[8] = '7';
-gpgchk[9] = '5';
-gpgchk[10] = 'D';
-gpgchk[11] = '0';
-gpgchk[12] = '1';
-gpgchk[13] = 'B';
-gpgchk[14] = '4';
-gpgchk[15] = '4';
-gpgchk[16] = 'B';
-gpgchk[17] = '5';
-gpgchk[18] = 'E';
-gpgchk[19] = '3';
-gpgchk[20] = 'A';
-gpgchk[21] = '4';
-gpgchk[22] = '0';
-gpgchk[23] = 'E';
-gpgchk[24] = '4';
-gpgchk[25] = '4';
-gpgchk[26] = '0';
-gpgchk[27] = '1';
-gpgchk[28] = '6';
-gpgchk[29] = '3';
-gpgchk[30] = '3';
-gpgchk[31] = '3';
-gpgchk[32] = 'C';
-gpgchk[33] = 'F';
-gpgchk[34] = '3';
-gpgchk[35] = 'C';
-gpgchk[36] = '5';
-gpgchk[37] = '6';
-gpgchk[38] = 'A';
-gpgchk[39] = '7';
-gpgchk[40] = 'A';
-gpgchk[41] = 'B';
-gpgchk[42] = 'D';
-gpgchk[43] = '9';
-gpgchk[44] = '1';
-gpgchk[45] = '9';
-gpgchk[46] = '6';
-gpgchk[47] = '6';
-gpgchk[48] = '\0';
-#endif
Index: /trunk/include/sh_sig.h
===================================================================
--- /trunk/include/sh_sig.h	(revision 550)
+++ /trunk/include/sh_sig.h	(revision 550)
@@ -0,0 +1,66 @@
+/* SAMHAIN file system integrity testing                                   */
+/* Copyright (C) 1999 Rainer Wichmann                                      */
+/*                                                                         */
+/*  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.              */
+
+#if defined(WITH_SIG) 
+
+#ifndef SH_SIG_H
+#define SH_SIG_H
+
+typedef enum {
+  SIG_CONF,
+  SIG_DATA
+} ShSigFile;
+
+/* Top level function to verify file.
+ */
+SL_TICKET sh_sig_extract_signed(SL_TICKET fd);
+SL_TICKET sh_sig_extract_signed_data(SL_TICKET fd);
+
+/* this function exits if configuration file
+ * and/or database cannot be verified; otherwise returns 0
+ */
+int sh_sig_check_signature (SL_TICKET file, ShSigFile what);
+
+int sh_sig_msg_start(const char * line);
+int sh_sig_msg_startdata(const char * line);
+int sh_sig_msg_end(const char * line);
+int sh_sig_data_end(const char * line);
+
+/* log successful startup
+ */
+void sh_sig_log_startup (void);
+
+#endif
+
+/* #ifdef WITH_SIG */
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /trunk/samhain-install.sh.in
===================================================================
--- /trunk/samhain-install.sh.in	(revision 549)
+++ /trunk/samhain-install.sh.in	(revision 550)
@@ -1339,4 +1339,5 @@
 
     GPGPATH=@mygpg@
+    SIGNIFY_PATH=@mysignify@
     TARGETKEYID=@mykeyid@
     KEYTAG=@mykeytag@
@@ -1416,4 +1417,40 @@
 	    cp ${RCFILE} samhainrc.pre
         fi
+    elif test x"${SIGNIFY_PATH}" != x
+    then
+	echo
+	echo "You need to sign the config file now"
+	echo
+	test -z "$verbose" || echo "  ${SIGNIFY_PATH} -Se -s ~/.signify/samhain.sec -m $RCFILE"
+	if test x"${NTEST}" = "x-DSH_WITH_SERVER"
+	then
+	    myident_uid=`(cat /etc/passwd; ypcat passwd) 2>/dev/null |\
+		  grep "^${samhain}:" | awk -F: '{ print $3; }'`
+	    if test x"${myident_uid}" != x
+	    then
+		DOT_SIGNIFY=`eval echo ~${samhain}/.signify`
+	        test -z "$verbose" || echo "  using home directory ${DOT_SIGNIFY}"
+		${SIGNIFY_PATH} -Se -s ${DOT_GNUPG}/samhain.sec $RCFILE
+	    else
+		${SIGNIFY_PATH} -Se -s  ~/.signify/samhain.sec -m $RCFILE
+	    fi
+	else
+	    ${SIGNIFY_PATH} -Se -s  ~/.signify/samhain.sec -m $RCFILE
+	fi
+
+	if test -f ${RCFILE}.sig
+	then
+	    test -z "$verbose" || echo "  mv -f ${RCFILE}.sig samhainrc.pre"
+	    mv -f ${RCFILE}.sig samhainrc.pre
+	else
+	    echo "**********************************************************"
+	    echo
+	    echo "${0}: ERROR: cannot find signed file ${RCFILE}.sig"
+	    echo
+	    echo "   --- You need to sign the configuration file ---"
+	    echo
+	    echo "**********************************************************"
+	    cp ${RCFILE} samhainrc.pre
+        fi
     else
 	test -z "$verbose" || echo "  cp $RCFILE samhainrc.pre"
Index: /trunk/scripts/samhainadmin-gpg.pl.in
===================================================================
--- /trunk/scripts/samhainadmin-gpg.pl.in	(revision 550)
+++ /trunk/scripts/samhainadmin-gpg.pl.in	(revision 550)
@@ -0,0 +1,726 @@
+#! /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 550)
+++ /trunk/scripts/samhainadmin-sig.pl.in	(revision 550)
@@ -0,0 +1,636 @@
+#! /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: unk/scripts/samhainadmin.pl.in
===================================================================
--- /trunk/scripts/samhainadmin.pl.in	(revision 549)
+++ 	(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/yuleadmin.pl.in
===================================================================
--- /trunk/scripts/yuleadmin.pl.in	(revision 549)
+++ /trunk/scripts/yuleadmin.pl.in	(revision 550)
@@ -38,15 +38,8 @@
 my $base = basename($0);
 
-#my $cfgfile  = "yulerc";
-#my $yule     = "./yule";
-#my $gpg      = "/usr/bin/gpg";
-
 my $cfgfile  = "@myconffile@";
 my $yule     = "@sbindir@/@install_name@";
-my $gpg      = "@mygpg@";
 
 $cfgfile  =~ s/^REQ_FROM_SERVER//;
-
-$gpg = "gpg" if ($gpg eq "");
 
 sub usage() {
Index: /trunk/src/depend-gen.c
===================================================================
--- /trunk/src/depend-gen.c	(revision 549)
+++ /trunk/src/depend-gen.c	(revision 550)
@@ -245,5 +245,5 @@
 	   *
 	   **************************************************/
-	  if (0 == strcmp(p, "sh_gpg_chksum.h") ||
+	  if (0 == strcmp(p, "sh_sig_chksum.h") ||
 	      0 == strcmp(p, "sh_gpg_fp.h"))
 	    {
Index: /trunk/src/samhain.c
===================================================================
--- /trunk/src/samhain.c	(revision 549)
+++ /trunk/src/samhain.c	(revision 550)
@@ -77,5 +77,5 @@
 
 #include "sh_tiger.h"
-#include "sh_gpg.h"
+#include "sh_sig.h"
 #include "sh_mem.h"
 #include "sh_xfer.h"
@@ -1907,7 +1907,7 @@
 #if defined(SH_WITH_SERVER) && !defined(SH_WITH_CLIENT)
 
-#if (defined(WITH_GPG) || defined(WITH_PGP))
+#if defined(WITH_GPG)
   /* log startup */
-  sh_gpg_log_startup ();
+  sh_sig_log_startup ();
 #else
   sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_1H,
@@ -1930,7 +1930,7 @@
   if (sh.flag.checkSum == SH_CHECK_CHECK) 
     {
-#if (defined(WITH_GPG) || defined(WITH_PGP))
+#if defined(WITH_GPG)
       /* log startup */
-      sh_gpg_log_startup ();
+      sh_sig_log_startup ();
 #else
       sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_2H,
@@ -1942,7 +1942,7 @@
   else
     {
-#if (defined(WITH_GPG) || defined(WITH_PGP))
+#if defined(WITH_GPG)
       /* log startup */
-      sh_gpg_log_startup ();
+      sh_sig_log_startup ();
 #else
       sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_1H,
Index: /trunk/src/sh_calls.c
===================================================================
--- /trunk/src/sh_calls.c	(revision 549)
+++ /trunk/src/sh_calls.c	(revision 550)
@@ -533,6 +533,6 @@
 
 long int retry_aud_execve  (const char * file, int line, 
-			    const  char *dateiname, char * argv[],
-			    char * envp[])
+			    const  char *dateiname, char *const argv[],
+			    char *const envp[])
 {
   uid_t a = geteuid();
Index: /trunk/src/sh_dbIO.c
===================================================================
--- /trunk/src/sh_dbIO.c	(revision 549)
+++ /trunk/src/sh_dbIO.c	(revision 550)
@@ -31,5 +31,5 @@
 #include "sh_hash.h"
 #include "sh_dbIO.h"
-#include "sh_gpg.h"
+#include "sh_sig.h"
 #include "sh_tiger.h"
 #include "sh_xfer.h"
@@ -852,10 +852,10 @@
 static SL_TICKET verify_data (SL_TICKET fd)
 {
-#if defined(WITH_GPG) || defined(WITH_PGP)
+#if defined(WITH_SIG)
   SL_TICKET fdTmp;
 
   /* extract the data and copy to temporary file
    */
-  fdTmp = sh_gpg_extract_signed(fd);
+  fdTmp = sh_sig_extract_signed(fd);
 
   if (sig_termfast == 1)  /* SIGTERM */
@@ -871,5 +871,5 @@
   /* Validate signature of open file.
    */
-  if (0 != sh_gpg_check_sign (fd, SIG_DATA))
+  if (0 != sh_sig_check_signature (fd, SIG_DATA))
     {
       sl_close(fd);
@@ -877,4 +877,8 @@
     }
   sl_rewind (fd);
+
+  fdTmp = sh_sig_extract_signed_data(fd);
+  sl_close(fd);
+  fd = fdTmp;  
 #endif
 
Index: /trunk/src/sh_getopt.c
===================================================================
--- /trunk/src/sh_getopt.c	(revision 549)
+++ /trunk/src/sh_getopt.c	(revision 550)
@@ -481,8 +481,8 @@
 #ifdef WITH_GPG
   if (num > 0) fputc ('\n', stdout);
-  printf (_(" GnuPG signatures (%s)"), DEFAULT_GPG_PATH); ++num;
-#ifdef HAVE_GPG_CHECKSUM
-  if (num > 0) fputc ('\n', stdout);
-  printf (_("   -- GnuPG checksum:  %s"), GPG_HASH); ++num;
+  printf (_(" GnuPG signatures (%s)"), DEFAULT_SIG_PATH); ++num;
+#ifdef HAVE_SIG_CHECKSUM
+  if (num > 0) fputc ('\n', stdout);
+  printf (_("   -- GnuPG checksum:  %s"), SIG_HASH); ++num;
 #endif
 #ifdef USE_FINGERPRINT
Index: unk/src/sh_gpg.c
===================================================================
--- /trunk/src/sh_gpg.c	(revision 549)
+++ 	(revision )
@@ -1,1035 +1,0 @@
-/* SAMHAIN file system integrity testing                                   */
-/* Copyright (C) 1999, 2000 Rainer Wichmann                                */
-/*                                                                         */
-/*  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.              */
-
-#include "config_xor.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-
-#if defined(WITH_GPG) || defined(WITH_PGP)
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#if defined(SH_WITH_SERVER)
-#include <pwd.h>
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <sys/wait.h>
-
-#include <string.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-
-
-#if !defined(O_NONBLOCK)
-#if defined(O_NDELAY)
-#define O_NONBLOCK  O_NDELAY
-#else
-#define O_NONBLOCK  0
-#endif
-#endif
-
-
-#include "samhain.h"
-#include "sh_utils.h"
-#include "sh_error.h"
-#include "sh_tiger.h"
-#if defined(SH_WITH_SERVER)
-#define SH_NEED_PWD_GRP 1
-#include "sh_static.h"
-#endif
-#include "sh_gpg.h"
-
-static struct {
-  char     conf_id[SH_MINIBUF+1];
-  char     conf_fp[SH_MINIBUF+1];
-  char     data_id[SH_MINIBUF+1];
-  char     data_fp[SH_MINIBUF+1];
-} gp;
-
-typedef struct {
-  pid_t    pid;
-  FILE   * pipe;
-} sh_gpg_popen_t;
-
-#define SH_GPG_OK      0
-#define SH_GPG_BAD     1
-#define SH_GPG_BADSIGN 2
-
-/* replace #if 0 by #if 1 and set an appropriate path in front of '/pdbg.'
- * for debugging
- */
-#if 0
-#define PDGBFILE "/pdbg."
-#endif
-
-#if defined(PDGBFILE)
-FILE * pdbg;
-FILE * pdbgc;
-#define PDBG_OPEN    pdbg = fopen(PDGBFILE"main",  "a")  
-#define PDBG_CLOSE   sl_fclose (FIL__, __LINE__, pdbg)
-#define PDBG(arg)    fprintf(pdbg,  "PDBG: step %d\n", arg); fflush(pdbg)
-#define PDBG_D(arg)  fprintf(pdbg,  "PDBG: %d\n", arg); fflush(pdbg)
-#define PDBG_S(arg)  fprintf(pdbg,  "PDBG: %s\n", arg); fflush(pdbg)
-
-#define PDBGC_OPEN   pdbgc = fopen(PDGBFILE"child", "a")  
-#define PDBGC_CLOSE  sl_fclose (FIL__, __LINE__, pdbgc)
-#define PDBGC(arg)   fprintf(pdbgc, "PDBG: step %d\n", arg); fflush(pdbgc)
-#define PDBGC_D(arg) fprintf(pdbgc, "PDBG: %d\n", arg); fflush(pdbgc)
-#define PDBGC_S(arg) fprintf(pdbgc, "PDBG: %s\n", arg); fflush(pdbgc)
-#else
-#define PDBG_OPEN    
-#define PDBG_CLOSE   
-#define PDBG(arg)    
-#define PDBG_D(arg)  
-#define PDBG_S(arg)  
-#define PDBGC_OPEN    
-#define PDBGC_CLOSE   
-#define PDBGC(arg)    
-#define PDBGC_D(arg)  
-#define PDBGC_S(arg)  
-#endif
-
-#undef  FIL__
-#define FIL__  _("sh_gpg.c")
-
-#ifdef GPG_HASH
-
-static int sh_gpg_checksum (SL_TICKET checkfd, int flag)
-{
-  char * test_gpg;
-  char * test_ptr1 = NULL;
-  char * test_ptr2 = NULL;
-  char   wstrip1[128];
-  char   wstrip2[128];
-  int    i, k;
-#include "sh_gpg_chksum.h"
-
-  SL_ENTER(_("sh_gpg_checksum"));
-
-  test_gpg = sh_tiger_hash_gpg (DEFAULT_GPG_PATH, checkfd, TIGER_NOLIM);
-  
-  test_ptr1 = strchr(GPG_HASH, ':');
-  if (test_gpg != NULL)
-    test_ptr2 = strchr(test_gpg, ':');
-  
-  if (test_ptr2 != NULL)
-    test_ptr2 += 2;
-  else
-    test_ptr2 = test_gpg;
-  if (test_ptr1 != NULL)
-    test_ptr1 += 2;
-  else
-    test_ptr1 = GPG_HASH;
-
-  /* Tue Jun 24 23:11:54 CEST 2003 (1.7.9) -- strip whitespace
-   */
-  k = 0;
-  for (i = 0; i < 127; ++i)
-    {
-      if (test_ptr1[i] == '\0')
-	break;
-      if (test_ptr1[i] != ' ')
-	{
-	  wstrip1[k] = test_ptr1[i];
-	  ++k;
-	}
-    }
-  wstrip1[k] = '\0';
-
-  for(i = 0; i < KEY_LEN; ++i)
-    {
-      if (gpgchk[i] != wstrip1[i]) 
-	{
-	  sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0, MSG_E_GPG_CHK, 
-			  gpgchk, wstrip1);
-	  break;
-	}
-    }
-
-  k = 0;
-  if (test_ptr2)
-    {
-      for (i = 0; i < 127; ++i)
-	{
-	  if (test_ptr2[i] == '\0')
-	    break;
-	  if (test_ptr2[i] != ' ')
-	    {
-	      wstrip2[k] = test_ptr2[i];
-	      ++k;
-	    }
-	}
-    }
-  wstrip2[k] = '\0';
-
-  if (0 != sl_strncmp(wstrip1, wstrip2, 127))
-    {
-      TPT(((0), FIL__, __LINE__, _("msg=<pgp checksum: %s>\n"), test_gpg));
-      TPT(((0), FIL__, __LINE__, _("msg=<Compiled-in : %s>\n"), GPG_HASH));
-      TPT(((0), FIL__, __LINE__, _("msg=<wstrip1     : %s>\n"), wstrip1));
-      TPT(((0), FIL__, __LINE__, _("msg=<wstrip2     : %s>\n"), wstrip2));
-      if (flag == 1)
-	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_GPG, 
-			GPG_HASH, test_gpg);
-      dlog(1, FIL__, __LINE__, _("The compiled-in checksum of the gpg binary\n(%s)\ndoes not match the actual checksum\n(%s).\nYou need to recompile with the correct checksum."), wstrip1, wstrip2);
-      SH_FREE(test_gpg);
-      SL_RETURN((-1), _("sh_gpg_checksum"));
-    }
-  SH_FREE(test_gpg);
-  SL_RETURN( (0), _("sh_gpg_checksum"));
-}
-#endif
-
-struct startup_info {
-  long   line;
-  char * program;
-  long   uid;
-  char * path;
-  char * key_uid;
-  char * key_id;
-};
-
-static struct startup_info startInfo = { 0, NULL, 0, NULL, NULL, NULL };
-
-void sh_gpg_log_startup (void)
-{
-  if (startInfo.program != NULL)
-    {
-      sh_error_handle ((-1), FIL__, startInfo.line, 0, MSG_START_GH,
-		       startInfo.program, startInfo.uid,
-		       startInfo.path,
-		       startInfo.key_uid, startInfo.key_id);
-    }
-  return;
-}
-
-static void sh_gpg_fill_startup (long line, char * program, long uid, char * path, 
-				 char * key_uid, char * key_id)
-{
-  startInfo.line    = line;
-  startInfo.program = sh_util_strdup(program);
-  startInfo.uid     = uid;
-  startInfo.path    = sh_util_strdup(path);
-  startInfo.key_uid = sh_util_strdup(key_uid);
-  startInfo.key_id  = sh_util_strdup(key_id);
-  return;
-}
-
-static FILE * sh_gpg_popen (sh_gpg_popen_t  *source, int fd, 
-			    int mode, char * id, char * homedir)
-{
-  extern int flag_err_debug;
-  int pipedes[2];
-  FILE * outf = NULL;
-  char * envp[2];
-  size_t len;
-  char   path[256];
-  char   cc1[32];
-  char   cc2[32];
-
-  char   cc0[2] = "-";
-  char   cc3[32];
-  char   cc4[SH_PATHBUF+32];
-  char   cc5[32];
-
-
-  char * arg[9];
-
-#if defined(HAVE_GPG_CHECKSUM)
-  SL_TICKET   checkfd = -1;
-  int         myrand;
-  int         i;
-#if defined(__linux__)
-  int         get_the_fd(SL_TICKET);
-  char        pname[128];
-  int         pfd;
-  int         val_return;
-#endif
-#endif
-
-  SL_ENTER(_("sh_gpg_popen"));
-
-  /* -- GnuPG -- */
-  sl_strlcpy (path,  DEFAULT_GPG_PATH,  256);
-  sl_strlcpy (cc1,   _("--status-fd"),  32);
-  sl_strlcpy (cc2,   _("--verify"),     32);
-  sl_strlcpy (cc3,   _("--homedir"),    32);
-  /* sl_strlcpy (cc4,   sh.effective.home, SH_PATHBUF+32); */
-  sl_strlcpy (cc4,   homedir,           SH_PATHBUF+32);
-  sl_strlcat (cc4,   _("/.gnupg"),      SH_PATHBUF+32);
-  sl_strlcpy (cc5,   _("--no-tty"),     32);
-
-  /* fprintf(stderr, "YULE: homedir=%s\n", homedir); */
-
-#if defined(SH_WITH_SERVER)
-  if (0 == sl_ret_euid())   /* privileges not dropped yet */
-    {
-      struct stat lbuf;
-      int         status_stat = 0;
-#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
-      struct passwd    pwd;
-      char          *  buffer = SH_ALLOC(SH_PWBUF_SIZE);
-      struct passwd *  tempres;
-      sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, SH_PWBUF_SIZE, &tempres);
-#else
-      struct passwd * tempres = sh_getpwnam(DEFAULT_IDENT);
-#endif
-
-      if (!tempres)
-	{
-	  dlog(1, FIL__, __LINE__, 
-	       _("User %s does not exist. Please add the user to your system.\n"), 
-	       DEFAULT_IDENT);
-	  status_stat = -1;
-	}
-      if (!tempres->pw_dir || tempres->pw_dir[0] == '\0')
-	{
-	  dlog(1, FIL__, __LINE__, 
-	       _("User %s does not have a home directory.\nPlease add the home directory for this user to your system.\n"), 
-	       DEFAULT_IDENT);
-	  status_stat = -2;
-	}
-      if (status_stat == 0)
-	{
-	  sl_strlcpy (cc4, tempres->pw_dir, SH_PATHBUF+32); 
-	  sl_strlcat (cc4,   _("/.gnupg"),      SH_PATHBUF+32); 
-	  status_stat =  retry_lstat(FIL__, __LINE__, cc4, &lbuf);
-	  if (status_stat == -1)
-	    {
-	      dlog(1, FIL__, __LINE__, 
-		   _("Gnupg directory %s for user %s\ndoes not exist or is not accessible.\nPlease add the directory and put the keyring (pubring.gpg) there\nto verify the configuration file.\n"),
-		   cc4, DEFAULT_IDENT);
-	      status_stat = -3;
-	    }
-	}
-      if (status_stat == 0 && lbuf.st_uid != tempres->pw_uid)
-	{
-	  dlog(1, FIL__, __LINE__, 
-	       _("Gnupg directory %s\nis not owned by user %s.\n"), 
-	       cc4, DEFAULT_IDENT);
-	  status_stat = -4;
-	}
-      if (status_stat == 0)
-	{
-	  sl_strlcat (cc4,   _("/pubring.gpg"),      SH_PATHBUF+32); 
-	  status_stat =  retry_lstat(FIL__, __LINE__, cc4, &lbuf);
-	  if (status_stat == -1)
-	    {
-	      dlog(1, FIL__, __LINE__, 
-		   _("Gnupg public keyring %s for user %s\ndoes not exist or is not accessible.\nPlease add the directory and put the keyring (pubring.gpg) there\nto verify the configuration file.\n"),
-		   cc4, DEFAULT_IDENT);
-	      status_stat = -5;
-	    }
-	}
-      if (status_stat == 0 && lbuf.st_uid != tempres->pw_uid)
-	{
-	  dlog(1, FIL__, __LINE__, 
-	       _("Gnupg public keyring %s\nis not owned by user %s.\n"), 
-	       cc4, DEFAULT_IDENT);
-	  status_stat = -6;
-	}
-      if (status_stat != 0)
-	{
-	  sh_error_handle((-1), FIL__, __LINE__, status_stat, MSG_EXIT_ABORT1, 
-			  sh.prg_name);
-	  aud_exit (FIL__, __LINE__, EXIT_FAILURE);
-	}
-      sl_strlcpy (cc4, tempres->pw_dir, SH_PATHBUF+32); 
-      sl_strlcat (cc4,   _("/.gnupg"),      SH_PATHBUF+32); 
-#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
-      SH_FREE(buffer);
-#endif
-    }
-#endif
-
-  arg[0] = path; 
-  arg[1] = cc1;
-  arg[2] = "1";
-  arg[3] = cc2;
-  arg[4] = cc3;
-  arg[5] = cc4;
-  arg[6] = cc5;
-  arg[7] = cc0;
-  arg[8] = NULL;
-
-  /* catch 'unused parameter' compiler warning
-   */
-  (void) mode;
-  (void) id;
-
-  /* use homedir of effective user
-   */
-  len = sl_strlen(sh.effective.home) + 6;
-  envp[0] = calloc(1, len); /* free() ok   */
-  if (envp[0] != NULL)
-	sl_snprintf (envp[0], len, _("HOME=%s"), sh.effective.home); 
-  envp[1] = NULL;
-
-  /* Create the pipe 
-   */
-  if (aud_pipe(FIL__, __LINE__, pipedes) < 0) 
-    {
-      if (envp[0] != NULL) 
-	free(envp[0]);
-      SL_RETURN( (NULL), _("sh_gpg_popen"));
-    }
-
-  fflush (NULL);
-  
-  source->pid = aud_fork(FIL__, __LINE__);
-  
-  /* Failure
-   */
-  if (source->pid == (pid_t) - 1) 
-    {
-      sl_close_fd(FIL__, __LINE__, pipedes[0]);
-      sl_close_fd(FIL__, __LINE__, pipedes[1]);
-      if (envp[0] != NULL) 
-	free(envp[0]);
-      SL_RETURN( (NULL), _("sh_gpg_popen"));
-    }
-
-  if (source->pid == (pid_t) 0) 
-    {
-
-      /* child - make read side of the pipe stdout 
-       */
-      if (retry_aud_dup2(FIL__, __LINE__,
-			pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0)
-	{
-	  TPT(((0), FIL__, __LINE__, _("msg=<dup2 on pipe failed>\n")));
-	  dlog(1, FIL__, __LINE__, _("Internal error: dup2 failed\n"));
-	  aud__exit(FIL__, __LINE__, EXIT_FAILURE);
-	}
-      
-      /* close the pipe descriptors 
-       */
-      sl_close_fd (FIL__, __LINE__, pipedes[STDIN_FILENO]);
-      sl_close_fd (FIL__, __LINE__, pipedes[STDOUT_FILENO]);
-      
-      if (retry_aud_dup2(FIL__, __LINE__, fd, STDIN_FILENO) < 0)
-	{
-	  TPT(((0), FIL__, __LINE__, _("msg=<dup2 on fd failed>\n")));
-	  dlog(1, FIL__, __LINE__, _("Internal error: dup2 failed\n"));
-	  aud__exit(FIL__, __LINE__, EXIT_FAILURE);
-	}
- 
-      /* don't leak file descriptors
-       */
-      sh_unix_closeall (3, -1, S_TRUE); /* in child process */
-
-      if (flag_err_debug != S_TRUE)
-	{
-	  if (NULL == freopen(_("/dev/null"), "r+", stderr))
-	    {
-	      dlog(1, FIL__, __LINE__, _("Internal error: freopen failed\n"));
-	      aud__exit(FIL__, __LINE__, EXIT_FAILURE);
-	    }
-	}
-
-
-      /* We should become privileged if SUID,
-       * to be able to read the keyring.
-       * We have checked that gpg is OK,
-       * AND that only a trusted user could overwrite
-       * gpg.
-       */
-      memset (skey, 0, sizeof(sh_key_t));
-      aud_setuid(FIL__, __LINE__, geteuid());
-      
-      PDBGC_OPEN;
-      PDBGC_D((int)getuid());
-      PDBGC_D((int)geteuid());
-
-      {
-	int i = 0;
-	while (arg[i] != NULL)
-	  {
-	    PDBGC_S(arg[i]);
-	    ++i;
-	  }
-      }
-      PDBGC_CLOSE;
-
-      /* exec the program */
-
-#if defined(__linux__) && defined(HAVE_GPG_CHECKSUM)
-      /* 
-       * --  emulate an fexecve with checksum testing
-       */
-      checkfd = sl_open_read(FIL__, __LINE__, DEFAULT_GPG_PATH, SL_NOPRIV);
-
-      if (0 != sh_gpg_checksum(checkfd, 0))
-	{
-	  sl_close(checkfd);
-	  aud__exit(FIL__, __LINE__, EXIT_FAILURE);
-	}
-
-      pfd = get_the_fd(checkfd);
-      do {
-	val_return = dup (pfd);
-      } while (val_return < 0 && errno == EINTR);
-      pfd = val_return;
-      sl_close(checkfd);
-      /* checkfd = -1; *//* never read */
-
-      sl_snprintf(pname, sizeof(pname), _("/proc/self/fd/%d"), pfd);
-      if (0 == access(pname, R_OK|X_OK))               /* flawfinder: ignore */
-
-	{
-	  fcntl  (pfd, F_SETFD, FD_CLOEXEC);
-	  retry_aud_execve (FIL__, __LINE__,  pname, arg, envp);
-	      
-	  dlog(1, FIL__, __LINE__, _("Unexpected error: execve %s failed\n"),
-	       pname);
-	  /* failed 
-	   */
-	  aud__exit(FIL__, __LINE__, EXIT_FAILURE);
-	}
-	  
-      /* procfs not working, go ahead 
-       */
-#endif
-
-#if defined(HAVE_GPG_CHECKSUM)
-      /* This is an incredibly ugly kludge to prevent an attacker
-       * from knowing when it is safe to slip in a fake executable
-       * between the integrity check and the execve
-       */
-      myrand = (int) taus_get ();
-
-      myrand = (myrand < 0) ? (-myrand) : myrand;
-      myrand = (myrand % 32) + 2;
-
-      for (i = 0; i < myrand; ++i)
-	{
-	  checkfd = sl_open_fastread(FIL__, __LINE__, 
-				     DEFAULT_GPG_PATH, SL_NOPRIV);
-
-	  if (0 != sh_gpg_checksum(checkfd, 0)) {
-	    aud__exit(FIL__, __LINE__, EXIT_FAILURE);
-	  }
-	  sl_close(checkfd);
-	}
-#endif
-
-      retry_aud_execve (FIL__, __LINE__, DEFAULT_GPG_PATH, arg, envp);
-      dlog(1, FIL__, __LINE__, _("Unexpected error: execve %s failed\n"),
-	   DEFAULT_GPG_PATH);
-      
-      /* failed 
-       */
-      TPT(((0), FIL__, __LINE__, _("msg=<execve failed>\n")));
-      dlog(1, FIL__, __LINE__, _("Unexpected error: execve failed\n"));
-      aud__exit(FIL__, __LINE__, EXIT_FAILURE);
-    }
-
-  /* parent
-   */
-
-  if (envp[0] != NULL) 
-    free(envp[0]);
-
-  sl_close_fd (FIL__, __LINE__, pipedes[STDOUT_FILENO]);
-  retry_fcntl (FIL__, __LINE__, pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
-  retry_fcntl (FIL__, __LINE__, pipedes[STDIN_FILENO], F_SETFL,  O_NONBLOCK);
-
-  outf = fdopen (pipedes[STDIN_FILENO], "r");
-  
-  if (outf == NULL) 
-    {
-      aud_kill (FIL__, __LINE__, source->pid, SIGKILL);
-      sl_close_fd (FIL__, __LINE__, pipedes[STDOUT_FILENO]);
-      waitpid (source->pid, NULL, 0);
-      source->pid = 0;
-      SL_RETURN( (NULL), _("sh_gpg_popen"));
-    }
-  
-  SL_RETURN( (outf), _("sh_gpg_popen"));
-}
-
-
-static int sh_gpg_pclose (sh_gpg_popen_t *source)
-{
-  int status = 0;
-  
-  SL_ENTER(_("sh_gpg_pclose"));
-
-  status = sl_fclose(FIL__, __LINE__, source->pipe);
-  if (status)
-    SL_RETURN( (-1), _("sh_gpg_pclose"));
-  
-  if (waitpid(source->pid, NULL, 0) != source->pid)
-    status = -1;
-  
-  source->pipe = NULL;
-  source->pid = 0;
-  SL_RETURN( (status), _("sh_gpg_pclose"));
-}
- 
-static
-int sh_gpg_check_file_sign(int fd, char * sign_id, char * sign_fp, 
-			   char * homedir, int whichfile)
-{
-  struct stat buf;
-  char line[256];
-  sh_gpg_popen_t  source;
-  int have_id = BAD, have_fp = BAD, status = 0;
-
-#ifdef HAVE_GPG_CHECKSUM
-  SL_TICKET checkfd;
-#endif
-
-  SL_ENTER(_("sh_gpg_check_file_sign"));
-
-  /* check whether GnuPG exists and has the correct checksum
-   */
-  TPT(((0), FIL__, __LINE__, _("msg=<Check signature>\n")));
-  TPT(((0), FIL__, __LINE__, _("msg=<gpg is %s>\n"), DEFAULT_GPG_PATH));
-
-  if (0 != retry_lstat(FIL__, __LINE__, DEFAULT_GPG_PATH, &buf))
-    {
-      char errbuf[SH_ERRBUF_SIZE];
-
-      status = errno;
-      sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, status, MSG_ERR_LSTAT,
-		      sh_error_message(status, errbuf, sizeof(errbuf)), DEFAULT_GPG_PATH);
-      SL_RETURN( SH_GPG_BAD, _("sh_gpg_check_file_sign"));
-    }
-
-  if (0 != tf_trust_check (DEFAULT_GPG_PATH, SL_YESPRIV))
-    SL_RETURN( SH_GPG_BAD, _("sh_gpg_check_file_sign"));
-
-#ifdef HAVE_GPG_CHECKSUM
-  checkfd = sl_open_read(FIL__, __LINE__, DEFAULT_GPG_PATH, SL_YESPRIV);
-
-  if (0 != sh_gpg_checksum(checkfd, 1))
-    {
-      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-		      _("Checksum mismatch"), 
-		      _("gpg_check_file_sign"));
-      sl_close(checkfd);
-      SL_RETURN( SH_GPG_BAD, _("sh_gpg_check_file_sign"));
-    }
-  sl_close(checkfd);
-#endif
-
-  TPT(((0), FIL__, __LINE__, _("msg=<Open pipe to check signature>\n")));
-
-  fflush(NULL);
- 
-  source.pipe   = sh_gpg_popen  ( &source, fd, 0, NULL, homedir );
-
-  if (NULL == source.pipe)
-    {
-      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-		      _("Could not open pipe"), 
-		      _("gpg_check_file_sign"));
-      SL_RETURN( SH_GPG_BAD, _("sh_gpg_check_file_sign"));
-    }
-
-  TPT(((0), FIL__, __LINE__, _("msg=<Open pipe success>\n")));
-
- xagain:
-
-  errno = 0;
-
-  while (NULL != fgets(line, sizeof(line), source.pipe))
-    {
-
-      TPT(((0), FIL__, __LINE__, _("msg=<gpg out: %s>\n"), line));
-      if (line[strlen(line)-1] == '\n')
-	line[strlen(line)-1] = ' ';
-      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-		      line, 
-		      _("gpg_check_file_sign"));
-
-      if (sl_strlen(line) < 18) 
-	continue;
-
-      /* Sun May 27 18:40:05 CEST 2001
-       */
-      if (0 == sl_strncmp(_("BADSIG"), &line[9], 6) ||
-	  0 == sl_strncmp(_("ERRSIG"), &line[9], 6) ||
-	  0 == sl_strncmp(_("NO_PUBKEY"), &line[9], 6) ||
-	  0 == sl_strncmp(_("NODATA"), &line[9], 6) ||
-	  0 == sl_strncmp(_("SIGEXPIRED"), &line[9], 6))
-	{
-	  if      (0 == sl_strncmp(_("BADSIG"), &line[9], 6)) {
-	    dlog(1, FIL__, __LINE__, 
-		 _("%s file is signed, but the signature is invalid."),
-		 ((whichfile == 1) ? _("Configuration") : _("Database")));
-	  } 
-	  else if (0 == sl_strncmp(_("NO_PUBKEY"), &line[9], 6)) {
-	    dlog(1, FIL__, __LINE__, 
-		 _("%s file is signed, but the public key to verify the signature is not in my keyring %s/.gnupg/pubring.asc."), 
-		 ((whichfile == 1) ? _("Configuration") : _("Database")),
-		 homedir);
-	  }
-	  else if (0 == sl_strncmp(_("ERRSIG"), &line[9], 6)) {
-	    dlog(1, FIL__, __LINE__, 
-		 _("%s file is signed, but the public key to verify the signature is not in my keyring %s/.gnupg/pubring.asc."), 
-		 ((whichfile == 1) ? _("Configuration") : _("Database")),
-		 homedir);
-	  }
-	  else if (0 == sl_strncmp(_("SIGEXPIRED"), &line[9], 6)) {
-	    dlog(1, FIL__, __LINE__, 
-		 _("%s file is signed, but the public key to verify the signature has expired."), 
-		 ((whichfile == 1) ? _("Configuration") : _("Database")));
-	  }
-	  else if (0 == sl_strncmp(_("NODATA"), &line[9], 6)) {
-	    dlog(1, FIL__, __LINE__, 
-		 _("%s file is not signed."), 
-		 ((whichfile == 1) ? _("Configuration") : _("Database")));
-	  }
-
-	  have_fp = BAD; have_id = BAD;
-	  break;
-	}
-      if (0 == sl_strncmp(_("GOODSIG"), &line[9], 7))
-	{
-	  sl_strlcpy (sign_id, &line[25], SH_MINIBUF+1);
-	  if (sign_id)
-	    sign_id[sl_strlen(sign_id)-1] = '\0';  /* remove trailing '"' */
-	  have_id = GOOD;
-	} 
-      if (0 == sl_strncmp(_("VALIDSIG"), &line[9], 8))
-	{
-	  strncpy (sign_fp, &line[18], 40);
-	  sign_fp[40] = '\0';
-	  have_fp = GOOD;
-	}
-    }
-
-  if (ferror(source.pipe) && errno == EAGAIN) 
-    {
-      /* sleep 10 ms to avoid starving the gpg child writing to the pipe */
-      retry_msleep(0,10); 
-      clearerr(source.pipe);
-      goto xagain;
-    }
- 
-  sh_gpg_pclose (&source);
-
-  TPT(((0), FIL__, __LINE__, _("msg=<Close pipe>\n")));
-
-  if (have_id == GOOD)
-    {
-      TPT(((0), FIL__, __LINE__, _("msg=<Got signator ID>\n")));
-    }
-  if (have_fp == GOOD)
-    {
-      TPT(((0), FIL__, __LINE__, _("msg=<Got fingerprint>\n")));
-    }
-
-  if (have_id == GOOD && have_fp == GOOD)
-    SL_RETURN( SH_GPG_OK, _("sh_gpg_check_file_sign"));
-  else
-    {
-      if (have_id == BAD)
-	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-			_("No good signature"), 
-			_("gpg_check_file_sign"));
-      else
-	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-			_("No fingerprint for key"), 
-			_("gpg_check_file_sign"));
-      SL_RETURN( SH_GPG_BADSIGN, _("sh_gpg_check_file_sign"));
-    }
-}
-
-int get_the_fd(SL_TICKET file_1);
-
-#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && \
-  defined(HAVE_GETPWNAM_R)
-#define USE_GETPWNAM_R 1
-#endif
-
-int sh_gpg_check_sign (long file, int what)
-{
-  int status = SH_GPG_BAD;
-  int fd = 0;
-
-  static int smsg = S_FALSE;
-  char  * tmp;
-
-  char  * sig_id;
-  char  * sig_fp;
-
-  char  * homedir = sh.effective.home;
-#if defined(SH_WITH_SERVER)
-  struct passwd * tempres;
-#if defined(USE_GETPWNAM_R)
-  struct passwd    pwd;
-  char           * buffer = SH_ALLOC(SH_PWBUF_SIZE);
-#endif
-#endif
-
-#ifdef USE_FINGERPRINT
-#include "sh_gpg_fp.h"
-#endif
-
-  SL_ENTER(_("sh_gpg_check_sign"));
-
-
-  if (what == SIG_CONF)
-    fd = get_the_fd(file);
-  if (what == SIG_DATA)
-    fd = get_the_fd(file);
-
-
-  if (fd < 0)
-    {
-      TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD = %d>\n"), fd));
-      dlog(1, FIL__, __LINE__, 
-	   _("This looks like an unexpected internal error.\n"));
-#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
-      SH_FREE(buffer);
-#endif
-      SL_RETURN( (-1), _("sh_gpg_check_sign"));
-    }
-  
-#if defined(SH_WITH_SERVER)
-#if defined(USE_GETPWNAM_R)
-      sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, SH_PWBUF_SIZE, &tempres);
-#else
-      tempres = sh_getpwnam(DEFAULT_IDENT);
-#endif
-      if ((tempres != NULL) && (0 == sl_ret_euid()))
-	{
-	  /* privileges not dropped yet*/
-	  homedir = tempres->pw_dir;
-	}
-#endif
-
-  if (what == SIG_CONF)
-    {
-      TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD = %d>\n"), fd));
-      status = sh_gpg_check_file_sign(fd, gp.conf_id, gp.conf_fp, homedir, 1);
-      TPT(((0), FIL__, __LINE__, _("msg=<CONF SIGUSR: |%s|>\n"), gp.conf_id));
-      TPT(((0), FIL__, __LINE__, _("msg=<CONF SIGFP:  |%s|>\n"), gp.conf_fp));
-      sig_id =  gp.conf_id; sig_fp = gp.conf_fp;
-    }
-
-  if (what == SIG_DATA)
-    {
-      TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD = %d>\n"), fd));
-      status = sh_gpg_check_file_sign(fd, gp.data_id, gp.data_fp, homedir, 2);
-      TPT(((0), FIL__, __LINE__, _("msg=<DATA SIGUSR: |%s|>\n"), gp.data_id));
-      TPT(((0), FIL__, __LINE__, _("msg=<DATA SIGFP:  |%s|>\n"), gp.data_fp));
-      sig_id =  gp.data_id; sig_fp = gp.data_fp;
-    }
-  
-  if (SH_GPG_OK == status)
-    {
-#ifdef USE_FINGERPRINT
-      if ((sl_strcmp(SH_GPG_FP, sig_fp) == 0))
-	{
-	  int i;
-
-	  for(i = 0; i < (int) sl_strlen(sig_fp); ++i) {
-	      if (gpgfp[i] != sig_fp[i]) {
-		sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0, 
-				MSG_E_GPG_FP, gpgfp, sig_fp);
-		break; }
-	  }
-
-	  if (smsg == S_FALSE) {
-	    tmp  = sh_util_safe_name(sig_id);
-	    sh_gpg_fill_startup (__LINE__, sh.prg_name, sh.real.uid,
-				 (sh.flag.hidefile == S_TRUE) ? 
-				 _("(hidden)") : file_path('C', 'R'), 
-				 tmp, 
-				 sig_fp);
-	    SH_FREE(tmp); }
-	  smsg = S_TRUE;
-
-#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
-	  SH_FREE(buffer);
-#endif
-	  SL_RETURN(0, _("sh_gpg_check_sign"));
-	}
-      else
-	{
-	  /* fp mismatch */
-	  dlog(1, FIL__, __LINE__, 
-	       _("The fingerprint of the signing key: %s\ndoes not match the compiled-in fingerprint: %s.\nTherefore the signature could not be verified.\n"), 
-	       sig_fp, SH_GPG_FP);
-	  sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-		      _("Fingerprint mismatch"), _("gpg_check_sign"));
-	  status = SH_GPG_BADSIGN;
-	}
-#else /* ifdef USE_FINGERPRINT */
-      if (smsg == S_FALSE)
-	{
-	  tmp = sh_util_safe_name(sig_id);
-	  sh_gpg_fill_startup (__LINE__,
-			       sh.prg_name, sh.real.uid,
-			       (sh.flag.hidefile == S_TRUE) ? 
-			       _("(hidden)") : file_path('C', 'R'), 
-			       tmp,  sig_fp);
-	  SH_FREE(tmp);
-	}
-      smsg = S_TRUE;
-
-#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
-      SH_FREE(buffer);
-#endif
-
-      SL_RETURN(0, _("sh_gpg_check_sign"));
-#endif /* !ifdef USE_FINGERPRINT */
-    }
-
-  if (status != SH_GPG_OK) 
-    {
-      uid_t   e_uid  = sl_ret_euid();
-      char  * e_home = sh.effective.home;
-
-#if defined(SH_WITH_SERVER)
-#if defined(USE_GETPWNAM_R)
-      struct passwd    e_pwd;
-      char          *  e_buffer = SH_ALLOC(SH_PWBUF_SIZE);
-      struct passwd *  e_tempres;
-      sh_getpwnam_r(DEFAULT_IDENT, &e_pwd, e_buffer, SH_PWBUF_SIZE, &e_tempres);
-#else
-      struct passwd * e_tempres = sh_getpwnam(DEFAULT_IDENT);
-#endif
-
-      if ((e_tempres != NULL) && (0 == sl_ret_euid()))   
-	{
-	  /* privileges not dropped yet */
-	  e_uid  = e_tempres->pw_uid;
-	  e_home = e_tempres->pw_dir;
-	}
-#endif
-      dlog(1, FIL__, __LINE__, 
-	   _("The signature of the configuration file or the file signature database\ncould not be verified. Possible reasons are:\n - gpg binary (%s) not found\n - invalid signature\n - the signature key is not in the private keyring of UID %d,\n - there is no keyring in %s/.gnupg, or\n - the file is not signed - did you move /filename.asc to /filename ?\nTo create a signed file, use (remove old signatures before):\n   gpg -a --clearsign --not-dash-escaped FILE\n   mv FILE.asc FILE\n"),
-	   DEFAULT_GPG_PATH,
-	   (int) e_uid, e_home);
-
-#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
-      SH_FREE(e_buffer);
-#endif
-    }
-
-  TPT(((0), FIL__, __LINE__, _("msg=<Status = %d>\n"), status));
-
-  return (-1); /* make compiler happy */
-}  
-
-#define FGETS_BUF 16384
-
-SL_TICKET sh_gpg_extract_signed(SL_TICKET fd)
-{
-  FILE * fin_cp = NULL;
-  char * buf    = NULL;
-  int    bufc;
-  int    flag_pgp    = S_FALSE;
-  int    flag_nohead = S_FALSE;
-  SL_TICKET fdTmp = (-1);
-  SL_TICKET open_tmp (void);
-
-  /* extract the data and copy to temporary file
-   */
-  fdTmp = open_tmp();
-  if (SL_ISERROR(fdTmp))
-    {
-      dlog(1, FIL__, __LINE__, _("Error opening temporary file.\n")); 
-      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-		      _("Error opening temporary file."), 
-		      _("sh_gpg_extract_signed"));
-      return -1;
-    }
-
-  fin_cp = fdopen(dup(get_the_fd(fd)), "rb");
-  buf = SH_ALLOC(FGETS_BUF);
-
-  while (NULL != fgets(buf, FGETS_BUF, fin_cp))
-    {
-      bufc = 0; 
-      while (bufc < FGETS_BUF) { 
-	if (buf[bufc] == '\n') { ++bufc; break; }
-	++bufc;
-      }
-
-      if (flag_pgp == S_FALSE &&
-	  (0 == sl_strcmp(buf, _("-----BEGIN PGP SIGNED MESSAGE-----\n"))||
-	   0 == sl_strcmp(buf, _("-----BEGIN PGP MESSAGE-----\n")))
-	  )
-	{
-	  flag_pgp = S_TRUE;
-	  sl_write(fdTmp, buf, bufc);
-	  continue;
-	}
-      
-      if (flag_pgp == S_TRUE && flag_nohead == S_FALSE)
-	{
-	  if (buf[0] == '\n')
-	    {
-	      flag_nohead = S_TRUE;
-	      sl_write(fdTmp, buf, 1);
-	      continue;
-	    }
-	  else if (0 == sl_strncmp(buf, _("Hash:"), 5) ||
-		   0 == sl_strncmp(buf, _("NotDashEscaped:"), 15))
-	    {
-	      sl_write(fdTmp, buf, bufc);
-	      continue;
-	    }
-	  else
-	    continue;
-	}
-    
-      if (flag_pgp == S_TRUE && buf[0] == '\n')
-	{
-	  sl_write(fdTmp, buf, 1);
-	}
-      else if (flag_pgp == S_TRUE)
-	{
-	  /* sl_write_line(fdTmp, buf, bufc); */
-	  sl_write(fdTmp, buf, bufc);
-	}
-      
-      if (flag_pgp == S_TRUE && 
-	  0 == sl_strcmp(buf, _("-----END PGP SIGNATURE-----\n")))
-	break;
-    }
-  SH_FREE(buf);
-  sl_fclose(FIL__, __LINE__, fin_cp); /* fin_cp = fdopen(dup(), "rb"); */
-  sl_rewind (fdTmp);
-
-  return fdTmp;
-}
-
-/* #ifdef WITH_GPG */
-#endif
-
-
-
-
-
-
-
-
Index: /trunk/src/sh_hash.c
===================================================================
--- /trunk/src/sh_hash.c	(revision 549)
+++ /trunk/src/sh_hash.c	(revision 550)
@@ -54,5 +54,5 @@
 #include "sh_error.h"
 #include "sh_tiger.h"
-#include "sh_gpg.h"
+#include "sh_sig.h"
 #include "sh_unix.h"
 #include "sh_files.h"
Index: /trunk/src/sh_readconf.c
===================================================================
--- /trunk/src/sh_readconf.c	(revision 549)
+++ /trunk/src/sh_readconf.c	(revision 550)
@@ -34,5 +34,5 @@
 #include "sh_files.h"
 #include "sh_xfer.h"
-#include "sh_gpg.h"
+#include "sh_sig.h"
 #include "sh_hash.h"
 #include "sh_dbIO.h"
@@ -352,6 +352,6 @@
   SL_TICKET    fdTmp = -1;
 #endif
-#if defined(WITH_GPG) || defined(WITH_PGP)
-  SL_TICKET    fdGpg = -1;
+#if defined(WITH_SIG) 
+  SL_TICKET    fdSIG = -1;
 #endif
   char * tmp;
@@ -369,5 +369,5 @@
   char   local_flag = 'R';
 
-#if defined(WITH_GPG) || defined(WITH_PGP)
+#if defined(WITH_SIG)
   int    signed_content = S_FALSE;
   int    true_content   = S_FALSE;
@@ -470,6 +470,6 @@
 	sl_write_line(fdTmp, line_in, sl_strlen(line_in));
       }
-#if defined(WITH_GPG) || defined(WITH_PGP)
-    if (0 == sl_strncmp(line_in, _("-----END PGP SIGNATURE-----"), 25))
+#if defined(WITH_SIG)
+    if (S_TRUE == sh_sig_data_end(line_in))
       break;
 #else
@@ -485,16 +485,16 @@
 #endif
 
-#if defined(WITH_GPG) || defined(WITH_PGP)
+#if defined(WITH_SIG)
 
   /* extract the data and copy to temporary file
    */
-  fdGpg = sh_gpg_extract_signed(fd);
+  fdSIG = sh_sig_extract_signed(fd);
 
   sl_close(fd);
-  fd = fdGpg;
+  fd = fdSIG;
 
   /* Validate signature of open file.
    */
-  if (0 != sh_gpg_check_sign (fd, SIG_CONF))
+  if (0 != sh_sig_check_signature (fd, SIG_CONF))
     {
       SH_FREE(line_in);
@@ -520,24 +520,17 @@
     /* Sun May 27 18:40:05 CEST 2001
      */
-#if defined(WITH_GPG) || defined(WITH_PGP)
+#if defined(WITH_SIG)
     if (signed_content == S_FALSE)
       { 
-	if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNED MESSAGE-----")))
+	if (S_TRUE == sh_sig_msg_start(line))
 	  signed_content = S_TRUE;
 	else 
 	  continue;
       }
-    else if (true_content == S_FALSE)
-      {
-	if (line[0] == '\n')
-	  true_content = S_TRUE;
-	else
-	  continue;
-      }
-    else if (signed_content == S_TRUE)
+    else /* if (signed_content == S_TRUE) */
       { 
-	if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNATURE-----")))
+	if (S_TRUE == sh_sig_msg_end(line))
 	  break;
-	else if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNED MESSAGE-----")))
+	else if (S_TRUE == sh_sig_msg_start(line))
 	  {
 	    sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
@@ -551,4 +544,12 @@
 	    aud_exit (FIL__, __LINE__,EXIT_FAILURE);
 	  }
+      }
+
+    if (true_content == S_FALSE) /* continue if in header */
+      {
+	if (S_TRUE == sh_sig_msg_startdata(line))
+	  true_content = S_TRUE;
+	else
+	  continue;
       }
 #endif
Index: /trunk/src/sh_sig.c
===================================================================
--- /trunk/src/sh_sig.c	(revision 550)
+++ /trunk/src/sh_sig.c	(revision 550)
@@ -0,0 +1,1761 @@
+/* SAMHAIN file system integrity testing                                   */
+/* Copyright (C) 1999, 2000 Rainer Wichmann                                */
+/*                                                                         */
+/*  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.              */
+
+#include "config_xor.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#if defined(WITH_SIG)
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#if defined(SH_WITH_SERVER)
+#include <pwd.h>
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+#include <string.h>
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+
+
+#if !defined(O_NONBLOCK)
+#if defined(O_NDELAY)
+#define O_NONBLOCK  O_NDELAY
+#else
+#define O_NONBLOCK  0
+#endif
+#endif
+
+
+#include "samhain.h"
+#include "sh_utils.h"
+#include "sh_error.h"
+#include "sh_tiger.h"
+#if defined(SH_WITH_SERVER)
+#define SH_NEED_PWD_GRP 1
+#include "sh_static.h"
+#endif
+#include "sh_sig.h"
+
+int get_the_fd(SL_TICKET file_1);
+
+#if defined(WITH_GPG)
+static struct {
+  char     conf_id[SH_MINIBUF+1];
+  char     conf_fp[SH_MINIBUF+1];
+  char     data_id[SH_MINIBUF+1];
+  char     data_fp[SH_MINIBUF+1];
+} gp;
+#endif
+
+typedef struct {
+  pid_t    pid;
+  FILE   * pipe;
+} sh_gpg_popen_t;
+
+#define SH_SIG_OK      0
+#define SH_SIG_BAD     1
+#define SH_SIG_BADSIGN 2
+
+/* replace #if 0 by #if 1 and set an appropriate path in front of '/pdbg.'
+ * for debugging
+ */
+#if 0
+#define PDGBFILE "/pdbg."
+#endif
+
+#if defined(PDGBFILE)
+FILE * pdbg;
+FILE * pdbgc;
+#define PDBG_OPEN    pdbg = fopen(PDGBFILE"main",  "a")  
+#define PDBG_CLOSE   sl_fclose (FIL__, __LINE__, pdbg)
+#define PDBG(arg)    fprintf(pdbg,  "PDBG: step %d\n", arg); fflush(pdbg)
+#define PDBG_D(arg)  fprintf(pdbg,  "PDBG: %d\n", arg); fflush(pdbg)
+#define PDBG_S(arg)  fprintf(pdbg,  "PDBG: %s\n", arg); fflush(pdbg)
+
+#define PDBGC_OPEN   pdbgc = fopen(PDGBFILE"child", "a")  
+#define PDBGC_CLOSE  sl_fclose (FIL__, __LINE__, pdbgc)
+#define PDBGC(arg)   fprintf(pdbgc, "PDBG: step %d\n", arg); fflush(pdbgc)
+#define PDBGC_D(arg) fprintf(pdbgc, "PDBG: %d\n", arg); fflush(pdbgc)
+#define PDBGC_S(arg) fprintf(pdbgc, "PDBG: %s\n", arg); fflush(pdbgc)
+#else
+#define PDBG_OPEN    
+#define PDBG_CLOSE   
+#define PDBG(arg)    
+#define PDBG_D(arg)  
+#define PDBG_S(arg)  
+#define PDBGC_OPEN    
+#define PDBGC_CLOSE   
+#define PDBGC(arg)    
+#define PDBGC_D(arg)  
+#define PDBGC_S(arg)  
+#endif
+
+#undef  FIL__
+#define FIL__  _("sh_sig.c")
+
+#if defined(SIG_HASH) || defined(SIG_KEY_HASH)
+
+typedef enum { SIG_HASH_REPORT, SIG_HASH_REPORTFULL, SIG_HASH_OTHER } checksum_flag;
+
+static int sh_sig_checksum (SL_TICKET checkfd, checksum_flag flag, const char * expected_in, const char * path)
+{
+  char * test_sig;
+  char * expected = NULL;
+  char * test_ptr1 = NULL;
+  char * test_ptr2 = NULL;
+  char   wstrip1[128];
+  char   wstrip2[128];
+  int    i, k;
+#include "sh_sig_chksum.h"
+
+  SL_ENTER(_("sh_sig_checksum"));
+
+  
+  if (flag == SIG_HASH_OTHER)
+    expected = sh_util_strdup(expected_in);
+  
+  if (flag == SIG_HASH_OTHER)
+    test_sig = sh_tiger_hash_gpg (path, checkfd, TIGER_NOLIM);
+  else
+    test_sig = sh_tiger_hash_gpg (DEFAULT_SIG_PATH, checkfd, TIGER_NOLIM);
+  
+  test_ptr1 = (flag == SIG_HASH_OTHER) ? strchr(expected, ':') : strchr(SIG_HASH, ':');
+  if (test_ptr1 != NULL)
+    test_ptr1 += 2;
+  else
+    test_ptr1 = (flag == SIG_HASH_OTHER) ? expected : SIG_HASH;
+
+  if (test_sig != NULL)
+    test_ptr2 = strchr(test_sig, ':');
+  if (test_ptr2 != NULL)
+    test_ptr2 += 2;
+  else
+    test_ptr2 = test_sig;
+
+  /* Tue Jun 24 23:11:54 CEST 2003 (1.7.9) -- strip whitespace
+   */
+  k = 0;
+  for (i = 0; i < 127; ++i)
+    {
+      if (test_ptr1[i] == '\0')
+	break;
+      if (test_ptr1[i] != ' ')
+	{
+	  wstrip1[k] = test_ptr1[i];
+	  ++k;
+	}
+    }
+  wstrip1[k] = '\0';
+
+  if (flag != SIG_HASH_OTHER)
+    {
+      for(i = 0; i < KEY_LEN; ++i)
+	{
+	  if (sigchk[i] != wstrip1[i]) 
+	    {
+	      sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0, MSG_E_GPG_CHK, 
+			      sigchk, wstrip1);
+	      break;
+	    }
+	}
+    }
+
+  k = 0;
+  if (test_ptr2)
+    {
+      for (i = 0; i < 127; ++i)
+	{
+	  if (test_ptr2[i] == '\0')
+	    break;
+	  if (test_ptr2[i] != ' ')
+	    {
+	      wstrip2[k] = test_ptr2[i];
+	      ++k;
+	    }
+	}
+    }
+  wstrip2[k] = '\0';
+
+  if (0 != sl_strncmp(wstrip1, wstrip2, 127))
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<sig checksum: %s>\n"), test_sig));
+      TPT(((0), FIL__, __LINE__, _("msg=<compiled in : %s>\n"), (flag == SIG_HASH_OTHER) ? expected : SIG_HASH));
+      TPT(((0), FIL__, __LINE__, _("msg=<wstrip1     : %s>\n"), wstrip1));
+      TPT(((0), FIL__, __LINE__, _("msg=<wstrip2     : %s>\n"), wstrip2));
+      if (flag == SIG_HASH_REPORTFULL)
+	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_GPG, 
+			SIG_HASH, test_sig);
+      if (flag == SIG_HASH_OTHER)
+	dlog(1, FIL__, __LINE__, _("The compiled-in checksum of the public key %s\n(%s)\ndoes not match the actual checksum\n(%s).\nYou need to recompile with the correct checksum."), path, wstrip1, wstrip2);
+      else
+	dlog(1, FIL__, __LINE__, _("The compiled-in checksum of the signature checking binary %s\n(%s)\ndoes not match the actual checksum\n(%s).\nYou need to recompile with the correct checksum."), DEFAULT_SIG_PATH, wstrip1, wstrip2);
+      SH_FREE(test_sig);
+      if (expected)
+	SH_FREE(expected);
+      SL_RETURN((-1), _("sh_sig_checksum"));
+    }
+  SH_FREE(test_sig);
+  if (expected)
+    SH_FREE(expected);
+  SL_RETURN( (0), _("sh_sig_checksum"));
+}
+#endif
+
+struct startup_info {
+  long   line;
+  char * program;
+  long   uid;
+  char * path;
+  char * key_uid;
+  char * key_id;
+};
+
+static struct startup_info startInfo = { 0, NULL, 0, NULL, NULL, NULL };
+
+static void sh_sig_fill_startup (long line, char * program, long uid, char * path, 
+				 char * key_uid, char * key_id)
+{
+  startInfo.line    = line;
+  startInfo.program = sh_util_strdup(program);
+  startInfo.uid     = uid;
+  startInfo.path    = sh_util_strdup(path);
+  if (key_uid)
+    startInfo.key_uid = sh_util_strdup(key_uid);
+  else
+    startInfo.key_uid = sh_util_strdup(_("(not given)"));
+  if (key_id)
+    startInfo.key_id  = sh_util_strdup(key_id);
+  else
+    startInfo.key_id  = sh_util_strdup(_("(not given)"));
+  return;
+}
+
+typedef enum { SIG_DATASIG, SIG_DATAONLY } extractlevel;
+
+
+static FILE * sh_sig_popen (char *const argv[], sh_gpg_popen_t  *source, int fd);
+
+
+static FILE * sh_sig_popen (char *const arg[], sh_gpg_popen_t  *source, int fd)
+{
+  size_t len;
+  extern int flag_err_debug;
+  int pipedes[2];
+  FILE * outf = NULL;
+  char * envp[2];
+
+#if defined(HAVE_SIG_CHECKSUM)
+  SL_TICKET   checkfd = -1;
+  int         myrand;
+  int         i;
+#if defined(__linux__)
+  int         get_the_fd(SL_TICKET);
+  char        pname[128];
+  int         pfd;
+  int         val_return;
+#endif
+#endif
+
+  SL_ENTER(_("sh_sig_popen"));
+
+  /* use homedir of effective user
+   */
+  len = sl_strlen(sh.effective.home) + 6;
+  envp[0] = calloc(1, len); /* free() ok   */
+  if (envp[0] != NULL)
+	sl_snprintf (envp[0], len, _("HOME=%s"), sh.effective.home); 
+  envp[1] = NULL;
+
+  /* Create the pipe 
+   */
+  if (aud_pipe(FIL__, __LINE__, pipedes) < 0) 
+    {
+      if (envp[0] != NULL) 
+	free(envp[0]);
+      SL_RETURN( (NULL), _("sh_gpg_popen"));
+    }
+
+  fflush (NULL);
+  
+  source->pid = aud_fork(FIL__, __LINE__);
+  
+  /* Failure
+   */
+  if (source->pid == (pid_t) - 1) 
+    {
+      sl_close_fd(FIL__, __LINE__, pipedes[0]);
+      sl_close_fd(FIL__, __LINE__, pipedes[1]);
+      if (envp[0] != NULL) 
+	free(envp[0]);
+      SL_RETURN( (NULL), _("sh_sig_popen"));
+    }
+
+  if (source->pid == (pid_t) 0) 
+    {
+
+      /* child - make read side of the pipe stdout 
+       */
+      if (retry_aud_dup2(FIL__, __LINE__,
+			pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0)
+	{
+	  TPT(((0), FIL__, __LINE__, _("msg=<dup2 on pipe failed>\n")));
+	  dlog(1, FIL__, __LINE__, _("Internal error: dup2 failed\n"));
+	  aud__exit(FIL__, __LINE__, EXIT_FAILURE);
+	}
+      
+      /* close the pipe descriptors 
+       */
+      sl_close_fd (FIL__, __LINE__, pipedes[STDIN_FILENO]);
+      sl_close_fd (FIL__, __LINE__, pipedes[STDOUT_FILENO]);
+      
+      if (retry_aud_dup2(FIL__, __LINE__, fd, STDIN_FILENO) < 0)
+	{
+	  TPT(((0), FIL__, __LINE__, _("msg=<dup2 on fd failed>\n")));
+	  dlog(1, FIL__, __LINE__, _("Internal error: dup2 failed\n"));
+	  aud__exit(FIL__, __LINE__, EXIT_FAILURE);
+	}
+ 
+      /* don't leak file descriptors
+       */
+      sh_unix_closeall (3, -1, S_TRUE); /* in child process */
+
+      if (flag_err_debug != S_TRUE)
+	{
+	  if (NULL == freopen(_("/dev/null"), "r+", stderr))
+	    {
+	      dlog(1, FIL__, __LINE__, _("Internal error: freopen failed\n"));
+	      aud__exit(FIL__, __LINE__, EXIT_FAILURE);
+	    }
+	}
+
+
+      /* We should become privileged if SUID,
+       * to be able to read the keyring.
+       * We have checked that gpg is OK,
+       * AND that only a trusted user could overwrite
+       * gpg.
+       */
+      memset (skey, 0, sizeof(sh_key_t));
+      aud_setuid(FIL__, __LINE__, geteuid());
+      
+      PDBGC_OPEN;
+      PDBGC_D((int)getuid());
+      PDBGC_D((int)geteuid());
+
+      {
+	int i = 0;
+	while (arg[i] != NULL)
+	  {
+	    PDBGC_S(arg[i]);
+	    ++i;
+	  }
+      }
+      PDBGC_CLOSE;
+
+      /* exec the program */
+
+#if defined(__linux__) && defined(HAVE_SIG_CHECKSUM)
+      /* 
+       * --  emulate an fexecve with checksum testing
+       */
+      checkfd = sl_open_read(FIL__, __LINE__, DEFAULT_SIG_PATH, SL_NOPRIV);
+
+      if (0 != sh_sig_checksum(checkfd, SIG_HASH_REPORT, NULL, NULL))
+	{
+	  sl_close(checkfd);
+	  aud__exit(FIL__, __LINE__, EXIT_FAILURE);
+	}
+
+      pfd = get_the_fd(checkfd);
+      do {
+	val_return = dup (pfd);
+      } while (val_return < 0 && errno == EINTR);
+      pfd = val_return;
+      sl_close(checkfd);
+      /* checkfd = -1; *//* never read */
+
+      sl_snprintf(pname, sizeof(pname), _("/proc/self/fd/%d"), pfd);
+      if (0 == access(pname, R_OK|X_OK))               /* flawfinder: ignore */
+
+	{
+	  fcntl  (pfd, F_SETFD, FD_CLOEXEC);
+	  retry_aud_execve (FIL__, __LINE__,  pname, arg, envp);
+	      
+	  dlog(1, FIL__, __LINE__, _("Unexpected error: execve %s failed\n"),
+	       pname);
+	  /* failed 
+	   */
+	  aud__exit(FIL__, __LINE__, EXIT_FAILURE);
+	}
+	  
+      /* procfs not working, go ahead 
+       */
+#endif
+
+#if defined(HAVE_SIG_CHECKSUM)
+      /* This is an incredibly ugly kludge to prevent an attacker
+       * from knowing when it is safe to slip in a fake executable
+       * between the integrity check and the execve
+       */
+      myrand = (int) taus_get ();
+
+      myrand = (myrand < 0) ? (-myrand) : myrand;
+      myrand = (myrand % 32) + 2;
+
+      for (i = 0; i < myrand; ++i)
+	{
+	  checkfd = sl_open_fastread(FIL__, __LINE__, 
+				     DEFAULT_SIG_PATH, SL_NOPRIV);
+
+	  if (0 != sh_sig_checksum(checkfd, SIG_HASH_REPORT, NULL, NULL)) {
+	    aud__exit(FIL__, __LINE__, EXIT_FAILURE);
+	  }
+	  sl_close(checkfd);
+	}
+#endif
+
+      retry_aud_execve (FIL__, __LINE__, DEFAULT_SIG_PATH, arg, envp);
+      dlog(1, FIL__, __LINE__, _("Unexpected error: execve %s failed\n"),
+	   DEFAULT_SIG_PATH);
+      
+      /* failed 
+       */
+      TPT(((0), FIL__, __LINE__, _("msg=<execve failed>\n")));
+      dlog(1, FIL__, __LINE__, _("Unexpected error: execve failed\n"));
+      aud__exit(FIL__, __LINE__, EXIT_FAILURE);
+    }
+
+  /* parent
+   */
+
+  if (envp[0] != NULL) 
+    free(envp[0]);
+
+  sl_close_fd (FIL__, __LINE__, pipedes[STDOUT_FILENO]);
+  retry_fcntl (FIL__, __LINE__, pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
+  retry_fcntl (FIL__, __LINE__, pipedes[STDIN_FILENO], F_SETFL,  O_NONBLOCK);
+
+  outf = fdopen (pipedes[STDIN_FILENO], "r");
+  
+  if (outf == NULL) 
+    {
+      aud_kill (FIL__, __LINE__, source->pid, SIGKILL);
+      sl_close_fd (FIL__, __LINE__, pipedes[STDOUT_FILENO]);
+      waitpid (source->pid, NULL, 0);
+      source->pid = 0;
+      SL_RETURN( (NULL), _("sh_sig_popen"));
+    }
+  
+  SL_RETURN( (outf), _("sh_sig_popen"));
+}
+
+
+static int sh_sig_pclose (sh_gpg_popen_t *source)
+{
+  int status = 0;
+  
+  SL_ENTER(_("sh_sig_pclose"));
+
+  status = sl_fclose(FIL__, __LINE__, source->pipe);
+  if (status)
+    SL_RETURN( (-1), _("sh_sig_pclose"));
+  
+  if (waitpid(source->pid, NULL, 0) != source->pid)
+    status = -1;
+  
+  source->pipe = NULL;
+  source->pid = 0;
+  SL_RETURN( (status), _("sh_sig_pclose"));
+}
+
+/* This is signify specific stuff 
+ */
+#if defined(WITH_SIGNIFY)
+
+#include <ctype.h>
+
+static
+int sh_signify_comp_comm(const char * line, size_t * commlen)
+{
+  /* check for a valid comment line: not exceeding 1023 chars and 
+   * starting with 'untrusted comment: ' */
+  static char   cmp[SH_MINIBUF];
+  static size_t cmp_len = 0;
+
+  size_t len = sl_strlen(line);
+  
+  if (cmp_len == 0) {
+    sl_strlcpy(cmp, _("untrusted comment: "), sizeof(cmp));
+    cmp_len = strlen(cmp);
+  }
+
+  if (line[len-1] == '\n') {
+    /* signify will replace the '\n' with '\0', so 1024 -> 1023, which fits */
+    if (len > 1024) return S_FALSE;
+    else            *commlen = len;
+  } else {
+    if (len > 1023) return S_FALSE;
+    else            *commlen = (len+1);
+  }
+
+  if (len >= cmp_len && 0 == strncmp(cmp, line, cmp_len))
+    return S_TRUE;
+  return S_FALSE;
+}
+
+static const char bto64_0[] = N_("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
+static char bto64[65] = { '\0' };
+
+static
+int sh_signify_comp_sig(const char * line, size_t commlen)
+{
+  char   cmp[128];
+  char   out[128];
+  size_t len = sl_strlen(line);
+  size_t i, j = 0;
+  int padf = 0;
+
+  if (bto64[0] == '\0')
+    memcpy(bto64, _(bto64_0), 65);
+  
+  if (line[len-1] == '\n') {
+    if ((len+commlen) > 2047) return S_FALSE;
+  } else {
+    if ((len+commlen) > 2046) return S_FALSE;
+  }
+
+  for (i = 0; i < len; ++i)
+    {
+      if (isspace(line[i])) {
+	/* signify will skip arbitrary space, using isspace() */
+	continue;
+      }
+      if (line[i] == '=') {
+	if (padf > 1) /* more than two padding '=' */
+	  return S_FALSE;
+	else
+	  ++padf;
+      } else if (!strchr(bto64, line[i]) || (line[i] == '=' && padf > 0)) {
+	return S_FALSE;
+      }
+      if (j < sizeof(cmp)) {
+	  cmp[j] = line[i]; ++j;
+      }
+    }
+
+  /* signature is 'Ed' + 8 byte random + 64 bytes = 74 bytes
+   * => 1 pad byte => 75 bytes => 100 b64 bytes */
+  if (j != 100 || padf != 1)
+    return S_FALSE;
+  
+  cmp[j] = '\0'; /* j == 100 */
+  sh_util_base64_dec((unsigned char *) out, (unsigned char *) cmp, j);
+  if(out[0] == 'E' && out[1] == 'd')
+    return S_TRUE;
+  
+  return S_FALSE;
+}
+static
+int sh_signify_msg_start(const char * line)
+{
+  static int  step = 0;
+  static size_t commlen = 0;
+
+  if (step == 0) {
+    if (S_TRUE == sh_signify_comp_comm(line, &commlen))
+      ++step;
+  }
+  else if (step == 1) {
+    if (S_TRUE == sh_signify_comp_sig(line, commlen)) {
+      ++step;
+    }
+    else {
+      step = 0; commlen = 0;
+    }
+  }
+  else if (step == 2) {
+    step = 0; commlen = 0;
+    return S_TRUE;
+  }
+  return S_FALSE;
+}
+
+static
+int sh_signify_msg_startdata(const char * line)
+{
+  (void) line;
+  return S_TRUE;
+}
+ 
+static
+int sh_signify_msg_end(const char * line)
+{
+  if (line[0] != '\0')
+    return S_FALSE;
+  return S_TRUE;
+}
+
+static
+int sh_signify_data_end(const char * line)
+{
+  if (line[0] == '[' && line[1] == 'E' && line[2] == 'O' &&
+      line[3] == 'F' && line[4] == ']')
+    return S_TRUE;
+  else if (line[0] != '\0')
+    return S_FALSE;
+  return S_TRUE;
+}
+
+static
+SL_TICKET sh_signify_extract_signed(SL_TICKET fd, extractlevel extract_level)
+{
+  const  int fgets_buf_size = 16384;
+  FILE * fin_cp = NULL;
+  char * buf    = NULL;
+  int    bufc;
+  char * comment = NULL;
+  size_t commlen = 0;
+  
+  int    flag_comm = S_FALSE;
+  int    flag_sig  = S_FALSE;
+  SL_TICKET fdTmp  = (-1);
+  SL_TICKET open_tmp (void);
+
+  /* extract the data and copy to temporary file
+   */
+  fdTmp = open_tmp();
+  if (SL_ISERROR(fdTmp))
+    {
+      dlog(1, FIL__, __LINE__, _("Error opening temporary file.\n")); 
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Error opening temporary file."), 
+		      _("sh_signify_extract_signed"));
+      return -1;
+    }
+
+  fin_cp = fdopen(dup(get_the_fd(fd)), "rb");
+  buf = SH_ALLOC(fgets_buf_size);
+
+  while (NULL != fgets(buf, fgets_buf_size, fin_cp))
+    {
+      
+      bufc = 0; 
+      while (bufc < fgets_buf_size) { 
+	if (buf[bufc] == '\n') { ++bufc; break; }
+	++bufc;
+      }
+
+      if (flag_comm == S_FALSE)
+	{
+	  if (sh_signify_comp_comm(buf, &commlen) == S_TRUE)
+	    {
+	      flag_comm = S_TRUE;
+	      if (extract_level == SIG_DATASIG)
+		{
+		  comment = sh_util_strdup(buf);
+		  commlen = bufc;
+		}
+	    }
+	  continue;
+	}
+      else if (flag_comm == S_TRUE && flag_sig == S_FALSE)
+	{
+	  if (sh_signify_comp_sig(buf, commlen) == S_TRUE)
+	    {
+	      flag_sig = S_TRUE;
+	      if (extract_level == SIG_DATASIG)
+		{
+		  sl_write(fdTmp, comment, commlen);
+		  sl_write(fdTmp, buf, bufc);
+		}
+	      if (comment != NULL)
+		SH_FREE(comment);
+	      comment = NULL;
+	    }
+	  else
+	    {
+	      if (comment != NULL)
+		SH_FREE(comment);
+	      comment = NULL; commlen = 0; flag_comm = 0;
+	    }
+	  continue;
+	}
+      
+      if (flag_sig == S_TRUE)
+	{
+	  sl_write(fdTmp, buf, bufc); 
+	}
+    }
+  if (comment != NULL)
+    SH_FREE(comment);
+  sl_fclose(FIL__, __LINE__, fin_cp);
+  sl_rewind (fdTmp);
+
+#if 0
+  fin_cp = fdopen(dup(get_the_fd(fdTmp)), "rb");
+  FILE * fout = fopen("xxx.out", "w+");
+  while (NULL != fgets(buf, fgets_buf_size, fin_cp))
+    {
+      fputs(buf, fout);
+    }
+  fclose(fout);
+  sl_rewind(fdTmp);
+#endif
+  
+  SH_FREE(buf);
+  return fdTmp;
+}
+
+
+static FILE * sh_signify_popen (sh_gpg_popen_t  *source, int fd, char * homedir)
+{
+  char   path[256];
+  char   cc1[32];
+  char   cc2[32];
+  char   cc3[32];
+  char   cc4[SH_PATHBUF+32];
+  char   cc5[32];
+  char   cc6[32];
+  char * argv[9];
+  FILE * retval = NULL;
+
+  struct stat lbuf;
+  int         status_stat = 0;
+
+#ifdef HAVE_SIG_KEY_HASH
+  SL_TICKET checkfd;
+#endif
+
+
+  SL_ENTER(_("sh_signify_popen"));
+
+  sl_strlcpy (path,  DEFAULT_SIG_PATH,  256);
+
+  sl_strlcpy (cc1,   _("-Vem"),         32);
+  sl_strlcpy (cc2,   _("/dev/null"),    32);
+
+  sl_strlcpy (cc3,   _("-p"),           32);
+  sl_strlcpy (cc4,   homedir,           SH_PATHBUF+32);
+  sl_strlcat (cc4,   _("/.signify/"),   SH_PATHBUF+32);
+  sl_strlcat (cc4,   SH_INSTALL_NAME,   SH_PATHBUF+32);
+  sl_strlcat (cc4,   _(".pub"),         SH_PATHBUF+32);
+
+  /* read signed message from stdin */
+  sl_strlcpy (cc5,   _("-x"),           32);
+  sl_strlcpy (cc6,   _("-"),            32);
+
+  status_stat =  retry_lstat(FIL__, __LINE__, cc4, &lbuf);
+  if (status_stat == -1)
+    {
+      dlog(1, FIL__, __LINE__, 
+	   _("Signify public key %s\ndoes not exist or is not accessible.\nPlease add the directory and put the key there\nto allow signature verification.\n"),
+	   cc4);
+      sh_error_handle((-1), FIL__, __LINE__, status_stat, MSG_EXIT_ABORT1, 
+		      sh.prg_name);
+      aud_exit (FIL__, __LINE__, EXIT_FAILURE);
+    }
+#ifdef HAVE_SIG_KEY_HASH
+  checkfd = sl_open_read(FIL__, __LINE__, cc4, SL_YESPRIV);
+
+  if (0 != sh_sig_checksum(checkfd, SIG_HASH_OTHER, SIG_KEY_HASH, cc4))
+    {
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Checksum mismatch for signify public key"), 
+		      _("signify_popen"));
+      sl_close(checkfd);
+      sh_error_handle((-1), FIL__, __LINE__, status_stat, MSG_EXIT_ABORT1, 
+		      sh.prg_name);
+      aud_exit (FIL__, __LINE__, EXIT_FAILURE);
+    }
+  sl_close(checkfd);
+#endif
+ 
+  argv[0] = path; 
+  argv[1] = cc1;
+  argv[2] = cc2;
+  argv[3] = cc3;
+  argv[4] = cc4;
+  argv[5] = cc5;
+  argv[6] = cc6;
+  argv[7] = NULL;
+
+  retval = sh_sig_popen(argv, source, fd);
+  SL_RETURN((retval), _("sh_signify_popen")); 
+}
+
+static
+int sh_signify_check_file_sign(int fd, char * homedir)
+{
+  struct stat buf;
+  char line[256];
+  sh_gpg_popen_t  source;
+  int status = 0;
+  unsigned int n_goodsig  = 0;
+  unsigned int n_lines    = 0;
+  
+#ifdef HAVE_SIG_CHECKSUM
+  SL_TICKET checkfd;
+#endif
+
+  SL_ENTER(_("sh_signify_check_file_sign"));
+
+  /* check whether signify exists and has the correct checksum
+   */
+  TPT(((0), FIL__, __LINE__, _("msg=<Check signature>\n")));
+  TPT(((0), FIL__, __LINE__, _("msg=<signify is %s>\n"), DEFAULT_SIG_PATH));
+
+  if (0 != retry_lstat(FIL__, __LINE__, DEFAULT_SIG_PATH, &buf))
+    {
+      char errbuf[SH_ERRBUF_SIZE];
+
+      status = errno;
+      sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, status, MSG_ERR_LSTAT,
+		      sh_error_message(status, errbuf, sizeof(errbuf)), DEFAULT_SIG_PATH);
+      SL_RETURN( SH_SIG_BAD, _("sh_signify_check_file_sign"));
+    }
+
+  if (0 != tf_trust_check (DEFAULT_SIG_PATH, SL_YESPRIV))
+    SL_RETURN( SH_SIG_BAD, _("sh_signify_check_file_sign"));
+
+#ifdef HAVE_SIG_CHECKSUM
+  checkfd = sl_open_read(FIL__, __LINE__, DEFAULT_SIG_PATH, SL_YESPRIV);
+
+  if (0 != sh_sig_checksum(checkfd, SIG_HASH_REPORTFULL, NULL, NULL))
+    {
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Checksum mismatch"), 
+		      _("signify_check_file_sign"));
+      sl_close(checkfd);
+      SL_RETURN( SH_SIG_BAD, _("sh_signify_check_file_sign"));
+    }
+  sl_close(checkfd);
+#endif
+
+  TPT(((0), FIL__, __LINE__, _("msg=<Open pipe to check signature>\n")));
+
+  fflush(NULL);
+ 
+  source.pipe   = sh_signify_popen  ( &source, fd, homedir );
+
+  if (NULL == source.pipe)
+    {
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Could not open pipe"), 
+		      _("signify_check_file_sign"));
+      SL_RETURN( SH_SIG_BAD, _("sh_signify_check_file_sign"));
+    }
+
+  TPT(((0), FIL__, __LINE__, _("msg=<Open pipe success>\n")));
+
+ xagain:
+
+  errno = 0;
+
+  while (NULL != fgets(line, sizeof(line), source.pipe))
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<signify out: %s>\n"), line));
+      if (line[strlen(line)-1] == '\n')
+	line[strlen(line)-1] = ' ';
+      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      line, 
+		      _("signify_check_file_sign"));
+
+      ++n_lines;
+
+      /* the '\n' has been replaced with ' ' for logging */ 
+      if (0 == sl_strcmp(_("Signature Verified "), line))
+	{
+	  ++n_goodsig;
+	} 
+    }
+
+  if (ferror(source.pipe) && errno == EAGAIN) 
+    {
+      /* sleep 10 ms to avoid starving the gpg child writing to the pipe */
+      retry_msleep(0,10); 
+      clearerr(source.pipe);
+      goto xagain;
+    }
+ 
+  if (0 != sh_sig_pclose (&source))
+    {
+	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+			_("Error on closing process pipe"), 
+			_("signify_check_file_sign"));
+	n_goodsig = 0;
+    }
+
+  TPT(((0), FIL__, __LINE__, _("msg=<Close pipe>\n")));
+
+  if (n_goodsig == 1 && n_lines == 1)
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<Signature Verified>\n")));
+      SL_RETURN( SH_SIG_OK, _("sh_signature_check_file_sign"));
+    }
+  else
+    {
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Error verifying file signature"), 
+		      _("signify_check_file_sign"));
+    }
+  SL_RETURN( SH_SIG_BADSIGN, _("sh_signature_check_file_sign"));
+}
+
+
+int sh_signify_check_signature (SL_TICKET file, ShSigFile what)
+{
+  int status = SH_SIG_BAD;
+  int fd = 0;
+
+  static int smsg = S_FALSE;
+
+  char  * homedir = sh.effective.home;
+  char  * home_alloc = NULL;
+#if defined(SH_WITH_SERVER)
+  struct passwd * tempres;
+#if defined(USE_GETPWNAM_R)
+  struct passwd    pwd;
+  char           * buffer = SH_ALLOC(SH_PWBUF_SIZE);
+#endif
+#endif
+
+  SL_ENTER(_("sh_signify_check_sign"));
+
+  (void) what;
+  
+  fd = get_the_fd(file);
+
+  if (fd < 0)
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD = %d>\n"), fd));
+      dlog(1, FIL__, __LINE__, 
+	   _("This looks like an unexpected internal error.\n"));
+#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
+      SH_FREE(buffer);
+#endif
+      SL_RETURN( (-1), _("sh_signify_check_sign"));
+    }
+  
+#if defined(SH_WITH_SERVER)
+#if defined(USE_GETPWNAM_R)
+  sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, SH_PWBUF_SIZE, &tempres);
+#else
+  tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
+  if ((tempres != NULL) && (0 == sl_ret_euid()))
+    {
+      /* privileges not dropped yet*/
+      homedir = tempres->pw_dir;
+    }
+#endif
+
+  home_alloc = sh_util_strdup(homedir);
+  
+  TPT(((0), FIL__, __LINE__, _("msg=<SIGNIFY_CHECK: FD = %d>\n"), fd));
+  status = sh_signify_check_file_sign(fd, homedir);
+  
+  if (status != SH_SIG_OK) 
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<Status = %d>\n"), status));
+      dlog(1, FIL__, __LINE__, 
+	   _("The signature of the configuration file or the file signature database\ncould not be verified. Possible reasons are:\n - signify binary (%s) not found\n - invalid signature\n - there is no keyfile in %s/.signify/%s.pub, or\n - the file is not signed - did you move /filename.sig to /filename ?\nTo create a signed file, use (remove old signatures before):\n   signify|signify-openbsd -Se -s KEYNAME.sec -m FILE\n   mv FILE.sig FILE\n"),
+	   DEFAULT_SIG_PATH, home_alloc, SH_INSTALL_NAME);
+      SH_FREE(home_alloc);
+      SL_RETURN( (-1), _("sh_signify_check_sign"));
+    }
+
+  if (smsg == S_FALSE)
+    {
+      sh_sig_fill_startup (__LINE__,
+			   sh.prg_name, sh.real.uid,
+			   (sh.flag.hidefile == S_TRUE) ? 
+			   _("(hidden)") : file_path('C', 'R'), 
+			   NULL,  NULL);
+    }
+  smsg = S_TRUE;
+
+  SH_FREE(home_alloc);
+  SL_RETURN(0, _("sh_signify_check_sign"));
+}  
+
+/* This is GPG specific stuff 
+ */
+#elif defined(WITH_GPG)
+static FILE * sh_gpg_popen (sh_gpg_popen_t  *source, int fd, char * homedir)
+{
+  char   path[256];
+  char   cc1[32];
+  char   cc2[32];
+
+  char   cc0[2] = "-";
+  char   cc3[32];
+  char   cc4[SH_PATHBUF+32];
+  char   cc5[32];
+  char * argv[9];
+  FILE * retval = NULL;
+
+
+  SL_ENTER(_("sh_gpg_popen"));
+
+  /* -- GnuPG -- */
+  sl_strlcpy (path,  DEFAULT_SIG_PATH,  256);
+  sl_strlcpy (cc1,   _("--status-fd"),  32);
+  sl_strlcpy (cc2,   _("--verify"),     32);
+  sl_strlcpy (cc3,   _("--homedir"),    32);
+  /* sl_strlcpy (cc4,   sh.effective.home, SH_PATHBUF+32); */
+  sl_strlcpy (cc4,   homedir,           SH_PATHBUF+32);
+  sl_strlcat (cc4,   _("/.gnupg"),      SH_PATHBUF+32);
+  sl_strlcpy (cc5,   _("--no-tty"),     32);
+
+#if defined(SH_WITH_SERVER)
+  if (0 == sl_ret_euid())   /* privileges not dropped yet */
+    {
+      struct stat lbuf;
+      int         status_stat = 0;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      struct passwd    pwd;
+      char          *  buffer = SH_ALLOC(SH_PWBUF_SIZE);
+      struct passwd *  tempres;
+      sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, SH_PWBUF_SIZE, &tempres);
+#else
+      struct passwd * tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
+
+      if (!tempres)
+	{
+	  dlog(1, FIL__, __LINE__, 
+	       _("User %s does not exist. Please add the user to your system.\n"), 
+	       DEFAULT_IDENT);
+	  status_stat = -1;
+	}
+      if (!tempres->pw_dir || tempres->pw_dir[0] == '\0')
+	{
+	  dlog(1, FIL__, __LINE__, 
+	       _("User %s does not have a home directory.\nPlease add the home directory for this user to your system.\n"), 
+	       DEFAULT_IDENT);
+	  status_stat = -2;
+	}
+      if (status_stat == 0)
+	{
+	  sl_strlcpy (cc4, tempres->pw_dir, SH_PATHBUF+32); 
+	  sl_strlcat (cc4,   _("/.gnupg"),      SH_PATHBUF+32); 
+	  status_stat =  retry_lstat(FIL__, __LINE__, cc4, &lbuf);
+	  if (status_stat == -1)
+	    {
+	      dlog(1, FIL__, __LINE__, 
+		   _("Gnupg directory %s for user %s\ndoes not exist or is not accessible.\nPlease add the directory and put the keyring (pubring.gpg) there\nto verify the configuration file.\n"),
+		   cc4, DEFAULT_IDENT);
+	      status_stat = -3;
+	    }
+	}
+      if (status_stat == 0 && lbuf.st_uid != tempres->pw_uid)
+	{
+	  dlog(1, FIL__, __LINE__, 
+	       _("Gnupg directory %s\nis not owned by user %s.\n"), 
+	       cc4, DEFAULT_IDENT);
+	  status_stat = -4;
+	}
+      if (status_stat == 0)
+	{
+	  sl_strlcat (cc4,   _("/pubring.gpg"),      SH_PATHBUF+32); 
+	  status_stat =  retry_lstat(FIL__, __LINE__, cc4, &lbuf);
+	  if (status_stat == -1)
+	    {
+	      dlog(1, FIL__, __LINE__, 
+		   _("Gnupg public keyring %s for user %s\ndoes not exist or is not accessible.\nPlease add the directory and put the keyring (pubring.gpg) there\nto verify the configuration file.\n"),
+		   cc4, DEFAULT_IDENT);
+	      status_stat = -5;
+	    }
+	}
+      if (status_stat == 0 && lbuf.st_uid != tempres->pw_uid)
+	{
+	  dlog(1, FIL__, __LINE__, 
+	       _("Gnupg public keyring %s\nis not owned by user %s.\n"), 
+	       cc4, DEFAULT_IDENT);
+	  status_stat = -6;
+	}
+      if (status_stat != 0)
+	{
+	  sh_error_handle((-1), FIL__, __LINE__, status_stat, MSG_EXIT_ABORT1, 
+			  sh.prg_name);
+	  aud_exit (FIL__, __LINE__, EXIT_FAILURE);
+	}
+      sl_strlcpy (cc4, tempres->pw_dir, SH_PATHBUF+32); 
+      sl_strlcat (cc4,   _("/.gnupg"),      SH_PATHBUF+32); 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      SH_FREE(buffer);
+#endif
+    }
+#endif
+
+  argv[0] = path; 
+  argv[1] = cc1;
+  argv[2] = "1";
+  argv[3] = cc2;
+  argv[4] = cc3;
+  argv[5] = cc4;
+  argv[6] = cc5;
+  argv[7] = cc0;
+  argv[8] = NULL;
+
+  retval = sh_sig_popen(argv, source, fd);
+  SL_RETURN((retval), _("sh_gpg_popen")); 
+}
+
+static
+int sh_gpg_check_file_sign(int fd, char * sign_id, char * sign_fp, 
+			   char * homedir, ShSigFile whichfile)
+{
+  struct stat buf;
+  char line[256];
+  sh_gpg_popen_t  source;
+  int have_id = BAD, have_fp = BAD, status = 0;
+  unsigned int n_newsig   = 0;
+  unsigned int n_goodsig  = 0;
+  unsigned int n_validsig = 0;
+  
+#ifdef HAVE_SIG_CHECKSUM
+  SL_TICKET checkfd;
+#endif
+
+  SL_ENTER(_("sh_gpg_check_file_sign"));
+
+  /* check whether GnuPG exists and has the correct checksum
+   */
+  TPT(((0), FIL__, __LINE__, _("msg=<Check signature>\n")));
+  TPT(((0), FIL__, __LINE__, _("msg=<gpg is %s>\n"), DEFAULT_SIG_PATH));
+
+  if (0 != retry_lstat(FIL__, __LINE__, DEFAULT_SIG_PATH, &buf))
+    {
+      char errbuf[SH_ERRBUF_SIZE];
+
+      status = errno;
+      sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, status, MSG_ERR_LSTAT,
+		      sh_error_message(status, errbuf, sizeof(errbuf)), DEFAULT_SIG_PATH);
+      SL_RETURN( SH_SIG_BAD, _("sh_gpg_check_file_sign"));
+    }
+
+  if (0 != tf_trust_check (DEFAULT_SIG_PATH, SL_YESPRIV))
+    SL_RETURN( SH_SIG_BAD, _("sh_gpg_check_file_sign"));
+
+#ifdef HAVE_SIG_CHECKSUM
+  checkfd = sl_open_read(FIL__, __LINE__, DEFAULT_SIG_PATH, SL_YESPRIV);
+
+  if (0 != sh_sig_checksum(checkfd, SIG_HASH_REPORTFULL, NULL, NULL))
+    {
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Checksum mismatch"), 
+		      _("gpg_check_file_sign"));
+      sl_close(checkfd);
+      SL_RETURN( SH_SIG_BAD, _("sh_gpg_check_file_sign"));
+    }
+  sl_close(checkfd);
+#endif
+
+  TPT(((0), FIL__, __LINE__, _("msg=<Open pipe to check signature>\n")));
+
+  fflush(NULL);
+ 
+  source.pipe   = sh_gpg_popen  ( &source, fd, homedir );
+
+  if (NULL == source.pipe)
+    {
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Could not open pipe"), 
+		      _("gpg_check_file_sign"));
+      SL_RETURN( SH_SIG_BAD, _("sh_gpg_check_file_sign"));
+    }
+
+  TPT(((0), FIL__, __LINE__, _("msg=<Open pipe success>\n")));
+
+ xagain:
+
+  errno = 0;
+
+  while (NULL != fgets(line, sizeof(line), source.pipe))
+    {
+
+      TPT(((0), FIL__, __LINE__, _("msg=<gpg out: %s>\n"), line));
+      if (line[strlen(line)-1] == '\n')
+	line[strlen(line)-1] = ' ';
+      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      line, 
+		      _("gpg_check_file_sign"));
+
+      if (sl_strlen(line) < 12) 
+	continue;
+
+      /* Sun May 27 18:40:05 CEST 2001
+       */
+      if (0 == sl_strncmp(_("BADSIG"),     &line[9], 6) ||
+	  0 == sl_strncmp(_("ERRSIG"),     &line[9], 6) ||
+	  0 == sl_strncmp(_("NO_PUBKEY"),  &line[9], 6) ||
+	  0 == sl_strncmp(_("NODATA"),     &line[9], 6) ||
+	  0 == sl_strncmp(_("ERROR"),      &line[9], 5) ||
+	  0 == sl_strncmp(_("SIGEXPIRED"), &line[9], 6))
+	{
+	  if      (0 == sl_strncmp(_("BADSIG"), &line[9], 6)) {
+	    dlog(1, FIL__, __LINE__, 
+		 _("%s file is signed, but the signature is invalid."),
+		 ((whichfile == SIG_CONF) ? _("Configuration") : _("Database")));
+	  } 
+	  else if (0 == sl_strncmp(_("NO_PUBKEY"), &line[9], 6)) {
+	    dlog(1, FIL__, __LINE__, 
+		 _("%s file is signed, but the public key to verify the signature is not in my keyring %s/.gnupg/pubring.asc."), 
+		 ((whichfile == SIG_CONF) ? _("Configuration") : _("Database")),
+		 homedir);
+	  }
+	  else if (0 == sl_strncmp(_("ERRSIG"), &line[9], 6)) {
+	    dlog(1, FIL__, __LINE__, 
+		 _("%s file is signed, but the public key to verify the signature is not in my keyring %s/.gnupg/pubring.asc."), 
+		 ((whichfile == SIG_CONF) ? _("Configuration") : _("Database")),
+		 homedir);
+	  }
+	  else if (0 == sl_strncmp(_("SIGEXPIRED"), &line[9], 6)) {
+	    dlog(1, FIL__, __LINE__, 
+		 _("%s file is signed, but the public key to verify the signature has expired."), 
+		 ((whichfile == SIG_CONF) ? _("Configuration") : _("Database")));
+	  }
+	  else if (0 == sl_strncmp(_("NODATA"), &line[9], 6)) {
+	    dlog(1, FIL__, __LINE__, 
+		 _("%s file is not signed."), 
+		 ((whichfile == SIG_CONF) ? _("Configuration") : _("Database")));
+	  }
+	  else if (0 == sl_strncmp(_("ERROR"), &line[9], 5)) {
+	    dlog(1, FIL__, __LINE__, 
+		 _("%s file is not correctly signed. An error occured while verifying the signature."), 
+		 ((whichfile == SIG_CONF) ? _("Configuration") : _("Database")));
+	  }
+
+	  have_fp = BAD; have_id = BAD;
+	  break;
+	}
+      if (0 == sl_strncmp(_("GOODSIG"), &line[9], 7))
+	{
+	  ++n_goodsig;
+	  sl_strlcpy (sign_id, &line[25], SH_MINIBUF+1);
+	  if (sign_id)
+	    sign_id[sl_strlen(sign_id)-1] = '\0';  /* remove trailing '"' */
+	  have_id = GOOD;
+	} 
+      else if (0 == sl_strncmp(_("VALIDSIG"), &line[9], 8))
+	{
+	  ++n_validsig;
+	  strncpy (sign_fp, &line[18], 40);
+	  sign_fp[40] = '\0';
+	  have_fp = GOOD;
+	}
+      else if (0 == sl_strncmp(_("NEWSIG"), &line[9], 6))
+	{
+	  ++n_newsig;
+	}
+      
+    }
+
+  if (ferror(source.pipe) && errno == EAGAIN) 
+    {
+      /* sleep 10 ms to avoid starving the gpg child writing to the pipe */
+      retry_msleep(0,10); 
+      clearerr(source.pipe);
+      goto xagain;
+    }
+ 
+  if (0 != sh_sig_pclose (&source))
+    {
+	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+			_("Error on closing process pipe"), 
+			_("gpg_check_file_sign"));
+	have_id = BAD;
+    }
+
+  TPT(((0), FIL__, __LINE__, _("msg=<Close pipe>\n")));
+
+  if (n_newsig != n_goodsig || n_newsig != n_validsig || n_newsig > 1)
+    {
+	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+			_("Too many or invalid signatures"), 
+			_("gpg_check_file_sign"));
+	have_id = BAD;
+    }
+  
+  if (have_id == GOOD)
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<Got signator ID>\n")));
+    }
+  if (have_fp == GOOD)
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<Got fingerprint>\n")));
+    }
+
+  if (have_id == GOOD && have_fp == GOOD)
+    SL_RETURN( SH_SIG_OK, _("sh_gpg_check_file_sign"));
+  else
+    {
+      if (have_id == BAD)
+	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+			_("No good signature"), 
+			_("gpg_check_file_sign"));
+      else
+	sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+			_("No fingerprint for key"), 
+			_("gpg_check_file_sign"));
+      SL_RETURN( SH_SIG_BADSIGN, _("sh_gpg_check_file_sign"));
+    }
+}
+
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && \
+  defined(HAVE_GETPWNAM_R)
+#define USE_GETPWNAM_R 1
+#endif
+
+static
+int sh_gpg_check_signature (SL_TICKET file, ShSigFile what)
+{
+  int status = SH_SIG_BAD;
+  int fd = 0;
+
+  static int smsg = S_FALSE;
+  char  * tmp;
+
+  char  * sig_id;
+  char  * sig_fp;
+
+  char  * homedir = sh.effective.home;
+#if defined(SH_WITH_SERVER)
+  struct passwd * tempres;
+#if defined(USE_GETPWNAM_R)
+  struct passwd    pwd;
+  char           * buffer = SH_ALLOC(SH_PWBUF_SIZE);
+#endif
+#endif
+
+#ifdef USE_FINGERPRINT
+#include "sh_gpg_fp.h"
+#endif
+
+  SL_ENTER(_("sh_gpg_check_sign"));
+
+
+  if (what == SIG_CONF)
+    fd = get_the_fd(file);
+  if (what == SIG_DATA)
+    fd = get_the_fd(file);
+
+
+  if (fd < 0)
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD = %d>\n"), fd));
+      dlog(1, FIL__, __LINE__, 
+	   _("This looks like an unexpected internal error.\n"));
+#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
+      SH_FREE(buffer);
+#endif
+      SL_RETURN( (-1), _("sh_gpg_check_sign"));
+    }
+  
+#if defined(SH_WITH_SERVER)
+#if defined(USE_GETPWNAM_R)
+      sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, SH_PWBUF_SIZE, &tempres);
+#else
+      tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
+      if ((tempres != NULL) && (0 == sl_ret_euid()))
+	{
+	  /* privileges not dropped yet*/
+	  homedir = tempres->pw_dir;
+	}
+#endif
+
+  if (what == SIG_CONF)
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD = %d>\n"), fd));
+      status = sh_gpg_check_file_sign(fd, gp.conf_id, gp.conf_fp, homedir, SIG_CONF);
+      TPT(((0), FIL__, __LINE__, _("msg=<CONF SIGUSR: |%s|>\n"), gp.conf_id));
+      TPT(((0), FIL__, __LINE__, _("msg=<CONF SIGFP:  |%s|>\n"), gp.conf_fp));
+      sig_id =  gp.conf_id; sig_fp = gp.conf_fp;
+    }
+
+  if (what == SIG_DATA)
+    {
+      TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD = %d>\n"), fd));
+      status = sh_gpg_check_file_sign(fd, gp.data_id, gp.data_fp, homedir, SIG_DATA);
+      TPT(((0), FIL__, __LINE__, _("msg=<DATA SIGUSR: |%s|>\n"), gp.data_id));
+      TPT(((0), FIL__, __LINE__, _("msg=<DATA SIGFP:  |%s|>\n"), gp.data_fp));
+      sig_id =  gp.data_id; sig_fp = gp.data_fp;
+    }
+  
+  if (SH_SIG_OK == status)
+    {
+#ifdef USE_FINGERPRINT
+      if ((sl_strcmp(SH_GPG_FP, sig_fp) == 0))
+	{
+	  int i;
+
+	  for(i = 0; i < (int) sl_strlen(sig_fp); ++i) {
+	      if (gpgfp[i] != sig_fp[i]) {
+		sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0, 
+				MSG_E_GPG_FP, gpgfp, sig_fp);
+		break; }
+	  }
+
+	  if (smsg == S_FALSE) {
+	    tmp  = sh_util_safe_name(sig_id);
+	    sh_sig_fill_startup (__LINE__, sh.prg_name, sh.real.uid,
+				 (sh.flag.hidefile == S_TRUE) ? 
+				 _("(hidden)") : file_path('C', 'R'), 
+				 tmp, 
+				 sig_fp);
+	    SH_FREE(tmp); }
+	  smsg = S_TRUE;
+
+#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
+	  SH_FREE(buffer);
+#endif
+	  SL_RETURN(0, _("sh_gpg_check_sign"));
+	}
+      else
+	{
+	  /* fp mismatch */
+	  dlog(1, FIL__, __LINE__, 
+	       _("The fingerprint of the signing key: %s\ndoes not match the compiled-in fingerprint: %s.\nTherefore the signature could not be verified.\n"), 
+	       sig_fp, SH_GPG_FP);
+	  sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Fingerprint mismatch"), _("gpg_check_sign"));
+	  status = SH_SIG_BADSIGN;
+	}
+#else /* ifdef USE_FINGERPRINT */
+      if (smsg == S_FALSE)
+	{
+	  tmp = sh_util_safe_name(sig_id);
+	  sh_sig_fill_startup (__LINE__,
+			       sh.prg_name, sh.real.uid,
+			       (sh.flag.hidefile == S_TRUE) ? 
+			       _("(hidden)") : file_path('C', 'R'), 
+			       tmp,  sig_fp);
+	  SH_FREE(tmp);
+	}
+      smsg = S_TRUE;
+
+#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
+      SH_FREE(buffer);
+#endif
+
+      /* status == OK and no fp checking */
+      SL_RETURN(0, _("sh_gpg_check_sign"));
+#endif /* !ifdef USE_FINGERPRINT */
+    }
+
+  if (status != SH_SIG_OK) 
+    {
+      uid_t   e_uid  = sl_ret_euid();
+      char  * e_home = sh.effective.home;
+
+#if defined(SH_WITH_SERVER)
+#if defined(USE_GETPWNAM_R)
+      struct passwd    e_pwd;
+      char          *  e_buffer = SH_ALLOC(SH_PWBUF_SIZE);
+      struct passwd *  e_tempres;
+      sh_getpwnam_r(DEFAULT_IDENT, &e_pwd, e_buffer, SH_PWBUF_SIZE, &e_tempres);
+#else
+      struct passwd * e_tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
+
+      if ((e_tempres != NULL) && (0 == sl_ret_euid()))   
+	{
+	  /* privileges not dropped yet */
+	  e_uid  = e_tempres->pw_uid;
+	  e_home = e_tempres->pw_dir;
+	}
+#endif
+      dlog(1, FIL__, __LINE__, 
+	   _("The signature of the configuration file or the file signature database\ncould not be verified. Possible reasons are:\n - gpg binary (%s) not found\n - invalid signature\n - the signature key is not in the private keyring of UID %d,\n - there is no keyring in %s/.gnupg, or\n - the file is not signed - did you move /filename.asc to /filename ?\nTo create a signed file, use (remove old signatures before):\n   gpg -a --clearsign --not-dash-escaped FILE\n   mv FILE.asc FILE\n"),
+	   DEFAULT_SIG_PATH,
+	   (int) e_uid, e_home);
+
+#if defined(SH_WITH_SERVER) && defined(USE_GETPWNAM_R)
+      SH_FREE(e_buffer);
+#endif
+    }
+
+  TPT(((0), FIL__, __LINE__, _("msg=<Status = %d>\n"), status));
+
+  SL_RETURN(-1, _("sh_gpg_check_sign")); /* make compiler happy */
+}  
+
+static int sh_gpg_comp(const char * line, const char * cmp)
+{
+  int retval = S_FALSE;
+
+  if (line && line[0] == '-' && line[1] == '-')
+    {
+      char * dup = sh_util_strdup(line);
+      char * tmp = dup + sl_strlen( dup );
+      --tmp;
+      if (*tmp == '\n') { *tmp = '\0'; --tmp; }
+      while( (*tmp == '\t' || *tmp == ' ' || *tmp == '\r' ) && tmp >= dup ) *tmp-- = '\0';
+
+      if (0 == sl_strcmp(dup, cmp))
+	retval = S_TRUE;
+      SH_FREE(dup);
+    }
+  return retval;
+}
+
+static
+int sh_gpg_msg_start(const char * line)
+{
+  static char cmp[SH_MINIBUF];
+  static int  initialized = 0;
+
+  if (initialized == 0) {
+    sl_strlcpy(cmp, _("-----BEGIN PGP SIGNED MESSAGE-----"), sizeof(cmp));
+    initialized = 1;
+  }
+  return sh_gpg_comp(line, cmp);
+}
+
+static
+int sh_gpg_msg_startdata(const char * line)
+{
+  if (line[0] == '\n')
+    return S_TRUE;
+  return S_FALSE;
+}
+
+static
+int sh_gpg_msg_end(const char * line)
+{
+  static char cmp[SH_MINIBUF];
+  static int  initialized = 0;
+
+  if (initialized == 0) {
+    sl_strlcpy(cmp, _("-----BEGIN PGP SIGNATURE-----"), sizeof(cmp));
+    initialized = 1;
+  }
+  return sh_gpg_comp(line, cmp);
+}
+
+static
+int sh_gpg_sig_end(const char * line)
+{
+  static char cmp[SH_MINIBUF];
+  static int  initialized = 0;
+
+  if (initialized == 0) {
+    sl_strlcpy(cmp, _("-----END PGP SIGNATURE-----"), sizeof(cmp));
+    initialized = 1;
+  }
+  return sh_gpg_comp(line, cmp);
+}
+
+static
+SL_TICKET sh_gpg_extract_signed(SL_TICKET fd, extractlevel extract_level)
+{
+  const  int fgets_buf_size = 16384;
+  FILE * fin_cp = NULL;
+  char * buf    = NULL;
+  int    bufc;
+  int    flag_pgp    = S_FALSE;
+  int    flag_nohead = S_FALSE;
+  SL_TICKET fdTmp = (-1);
+  SL_TICKET open_tmp (void);
+
+  /* extract the data and copy to temporary file
+   */
+  fdTmp = open_tmp();
+  if (SL_ISERROR(fdTmp))
+    {
+      dlog(1, FIL__, __LINE__, _("Error opening temporary file.\n")); 
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Error opening temporary file."), 
+		      _("sh_gpg_extract_signed"));
+      return -1;
+    }
+
+  fin_cp = fdopen(dup(get_the_fd(fd)), "rb");
+  buf = SH_ALLOC(fgets_buf_size);
+
+  while (NULL != fgets(buf, fgets_buf_size, fin_cp))
+    {
+      bufc = 0; 
+      while (bufc < fgets_buf_size) { 
+	if (buf[bufc] == '\n') { ++bufc; break; }
+	++bufc;
+      }
+
+      if (flag_pgp == S_FALSE && sh_gpg_msg_start(buf) == S_TRUE)
+	{
+	  flag_pgp = S_TRUE;
+	  if (extract_level == SIG_DATASIG)
+	    sl_write(fdTmp, buf, bufc);
+	  continue;
+	}
+      
+      if (flag_pgp == S_TRUE && flag_nohead == S_FALSE)
+	{
+	  /* Header finished */
+	  if (buf[0] == '\n')
+	    {
+	      flag_nohead = S_TRUE;
+	      if (extract_level == SIG_DATASIG)
+		sl_write(fdTmp, buf, 1);
+	      continue;
+	    }
+	  /* copy these headers */
+	  else if (0 == sl_strncmp(buf, _("Hash:"), 5) ||
+		   0 == sl_strncmp(buf, _("NotDashEscaped:"), 15))
+	    {
+	      if (extract_level == SIG_DATASIG)
+		sl_write(fdTmp, buf, bufc);
+	      continue;
+	    }
+	  /* ignore other headers */
+	  else
+	    continue;
+	}
+    
+      if (flag_pgp == S_TRUE && buf[0] == '\n')
+	{
+	  sl_write(fdTmp, buf, 1);
+	}
+      else if (flag_pgp == S_TRUE)
+	{
+	  if (extract_level == SIG_DATASIG) {
+	    sl_write(fdTmp, buf, bufc); 
+	  }
+	  else {
+	    if (sh_gpg_msg_end(buf) == S_TRUE)
+	      break;
+	    else
+	      sl_write(fdTmp, buf, bufc);
+	  }
+	}
+
+      /* This is after the copy has been done. */
+      if (flag_pgp == S_TRUE && sh_gpg_sig_end(buf) == S_TRUE)
+	break;
+    }
+  SH_FREE(buf);
+  sl_fclose(FIL__, __LINE__, fin_cp);
+  sl_rewind (fdTmp);
+
+  return fdTmp;
+}
+#endif
+
+/*********************************************************************
+ *
+ * Exported functions
+ *
+ *********************************************************************/
+
+int sh_sig_check_signature (SL_TICKET file, ShSigFile what)
+{
+#if defined(WITH_GPG)
+  return sh_gpg_check_signature (file, what);
+#elif defined(WITH_SIGNIFY)
+  return sh_signify_check_signature (file, what);
+#endif
+}
+
+SL_TICKET sh_sig_extract_signed(SL_TICKET fd)
+{
+#if defined(WITH_GPG)
+  return sh_gpg_extract_signed(fd, SIG_DATASIG);
+#elif defined(WITH_SIGNIFY)
+  return sh_signify_extract_signed(fd, SIG_DATASIG);
+#endif
+}
+
+SL_TICKET sh_sig_extract_signed_data(SL_TICKET fd)
+{
+#if defined(WITH_GPG)
+  return sh_gpg_extract_signed(fd, SIG_DATAONLY);
+#elif defined(WITH_SIGNIFY)
+  return sh_signify_extract_signed(fd, SIG_DATAONLY);
+#endif
+}
+
+int sh_sig_msg_start(const char * line)
+{
+#if defined(WITH_GPG)
+  return sh_gpg_msg_start(line);
+#elif defined(WITH_SIGNIFY)
+  return sh_signify_msg_start(line);
+#endif
+}
+
+int sh_sig_msg_startdata(const char * line)
+{
+#if defined(WITH_GPG)
+  return sh_gpg_msg_startdata(line);
+#elif defined(WITH_SIGNIFY)
+  return sh_signify_msg_startdata(line);
+#endif
+}
+
+int sh_sig_msg_end(const char * line)
+{
+#if defined(WITH_GPG)
+  return sh_gpg_msg_end(line);
+#elif defined(WITH_SIGNIFY)
+  return sh_signify_msg_end(line);
+#endif
+}
+
+int sh_sig_data_end(const char * line)
+{
+#if defined(WITH_GPG)
+  return sh_gpg_sig_end(line);
+#elif defined(WITH_SIGNIFY)
+  return sh_signify_data_end(line);
+#endif
+}
+
+void sh_sig_log_startup (void)
+{
+  if (startInfo.program != NULL)
+    {
+      sh_error_handle ((-1), FIL__, startInfo.line, 0, MSG_START_GH,
+		       startInfo.program, startInfo.uid,
+		       startInfo.path,
+		       startInfo.key_uid, startInfo.key_id);
+    }
+  return;
+}
+
+/* #ifdef WITH_SIG */
+#endif
+
+
+
+
+
+
+
+
Index: /trunk/src/sh_tools.c
===================================================================
--- /trunk/src/sh_tools.c	(revision 549)
+++ /trunk/src/sh_tools.c	(revision 550)
@@ -2075,5 +2075,5 @@
 #endif
 
-#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER) || defined(SH_STEALTH) || defined(WITH_GPG) || defined(WITH_PGP)
+#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER) || defined(SH_STEALTH) || defined(WITH_SIG)
 
 /* --------- secure temporary file ------------ */
Index: /trunk/src/sh_unix.c
===================================================================
--- /trunk/src/sh_unix.c	(revision 549)
+++ /trunk/src/sh_unix.c	(revision 550)
@@ -5407,4 +5407,5 @@
 {
   int                  add_off = 0, llen;
+  unsigned long        bread;
   static unsigned long off_data   = 0;
   static unsigned long max_data   = 0;
@@ -5454,6 +5455,11 @@
   /* --- Read one line. ---
    */
-  add_off   = hideout_hex_block(fd, (unsigned char *) str, len, &bytes_read);
-  off_data += add_off;
+  add_off   = hideout_hex_block(fd, (unsigned char *) str, len, &bread);
+  if (add_off > 0)
+    off_data += add_off;
+  bytes_read += bread;
+
+  if (bread == 0 || add_off <= 0) /* EOF */
+    str[0] = '\0';
 
   llen = sl_strlen(str);
@@ -5477,4 +5483,6 @@
   ASSERT_RET((len > 1), _("len > 1"), (0));
 
+  str[0] = '\0';
+  *bytes_read = 0;
   --len;
 
@@ -5494,12 +5502,15 @@
 	      do {
 		do {
+		  errno = 0;
 		  num = sl_read (fd, &c, 1);
 		} while (num == 0 && errno == EINTR);
 		if (num > 0)
 		  ++here;
-		else if (num == 0)
-		  SL_RETURN((0), _("hideout_hex_block"));
-		else 
+		else if (num == 0) {
 		  SL_RETURN((-1), _("hideout_hex_block"));
+		}
+		else {
+		  SL_RETURN((-1), _("hideout_hex_block"));
+		}
 	      } while (c == '\n' || c == '\t' || c == '\r' || 
 		       c == ' ');
@@ -5523,6 +5534,8 @@
   if (i != 0)
     str[i] = '\0';
+  else if (str[0] == '\n')
+    str[i+1] = '\0'; /* keep newline and terminate */
   else
-    str[i+1] = '\0'; /* keep newline and terminate */
+    str[0] = '\0';
   retval += here;
   *bytes_read += (bread/8);
Index: /trunk/test/gnupg/public-key.asc
===================================================================
--- /trunk/test/gnupg/public-key.asc	(revision 550)
+++ /trunk/test/gnupg/public-key.asc	(revision 550)
@@ -0,0 +1,20 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mI0EVY1+9AEEAMgqIppswdch0ErLLXbRnDgCMwhwaTydnu4NwvyDGSpy+32ODwSC
+lDC+SdiU/tx/gHTqFaVS3WJo9KcEgFNzkypdI2WYx5/ZCUNKZXIibJLcwE89mhf5
+Y4Gv6vVSZgW3nh+PJCumZG/ljb0X1ZDakHO03BEQJ9UfKo8akLhTnSWbABEBAAG0
+OFRlc3RzdWl0ZSBTYW1oYWluICh0ZXN0aW5nIG9ubHkpIDxuby1yZXBseUBsYS1z
+YW1obmEuZGU+iLgEEwECACIFAlWNfvQCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B
+AheAAAoJEE7Znk6KCzN68b0D/A+ykm13KWjqMGNOf6SF6girei2nvxIMkN2AVks0
+SXQxIbcu/Wzue+fhdHc2BzJTnlC6h9l/5RUNK5+D6+NRfFfCy6d1bESoUMlGK69u
+QnZSb9qepomJos3K9CQasKAsR1uE1mwzT4S7LPcqj1MWKwTnhLEKfG7I5o9MKyE9
+4AvHuI0EVY1+9AEEAL37L+v5AKOrFspzgpKj450XIelkLdkKlqqR7yrQZ+nZKZ9+
+4nWjxs/f+tJLwR9/XeK8YMktpvJkvGHzMz21Wz54iq8EfsTy6fRawfVkePxNAAZT
+cwf4DfCCVTpfEtJnVqoWWzy6elqbkgViLB346jLTUenm6cy8OhBfd5DAibfJABEB
+AAGInwQYAQIACQUCVY1+9AIbDAAKCRBO2Z5Oigszek1JA/94Nkn3UdzNiEogp0hn
+Z6Baabkok/mxULymZ+XWLrDDl2pi84msITxO1tiicZ3nP8zohdFrftFrH1zdoU5h
+n+GgGhsk9Frhj0gXYeBRbZ4NE1EUVoeY/xfe8T+uRAxa6Y0dvlzVsBUH0EAd0L6E
+GUU+G9Edi2T82HPsjeYOg+UI6Q==
+=C5Xk
+-----END PGP PUBLIC KEY BLOCK-----
Index: /trunk/test/gnupg/secret-key.asc
===================================================================
--- /trunk/test/gnupg/secret-key.asc	(revision 550)
+++ /trunk/test/gnupg/secret-key.asc	(revision 550)
@@ -0,0 +1,34 @@
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1
+
+lQHYBFWNfvQBBADIKiKabMHXIdBKyy120Zw4AjMIcGk8nZ7uDcL8gxkqcvt9jg8E
+gpQwvknYlP7cf4B06hWlUt1iaPSnBIBTc5MqXSNlmMef2QlDSmVyImyS3MBPPZoX
++WOBr+r1UmYFt54fjyQrpmRv5Y29F9WQ2pBztNwRECfVHyqPGpC4U50lmwARAQAB
+AAP+MLRD8DRXZCvnnVNb0CYHr38lgL+tc6Dcu4rgr4WMuY350J6g29WUDlo26Lq0
+Wt2xWYFd2/jSQnBMW1lWije8jmuc58sx/Gi3uuNWtSXPQlIK7aa3K6nlX+sXN24C
+w0VAIpNfpXYPPkHUq8YKyPV+9a32LxxE2gG+ZDzQfzrlLPUCANtU22P0IYtDSyaW
+7WCB5rjU7aAywDTC3gXuCVntaZLySpnBcjPlO3n4z6rD/qvsnPqPceKsqLaydrY2
+4s/YcscCAOmg9PpOVZ7Zpj+7BYgkGCcT+lrzzGWhFXHtJhCxa10qZuDZc7kKoDo/
+/FpAtm9WbuLBu3LuEsC1taiXYhUcoo0CAIcVVYHpw6yGcNpf+NegQDLAudYiCLzK
+Lvt4KKns7gIQse3PBzGKuNc98X+MQVf2iL/35XIF/eGZtoObrPLSi8axnbQ4VGVz
+dHN1aXRlIFNhbWhhaW4gKHRlc3Rpbmcgb25seSkgPG5vLXJlcGx5QGxhLXNhbWhu
+YS5kZT6IuAQTAQIAIgUCVY1+9AIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA
+CgkQTtmeTooLM3rxvQP8D7KSbXcpaOowY05/pIXqCKt6Lae/EgyQ3YBWSzRJdDEh
+ty79bO575+F0dzYHMlOeULqH2X/lFQ0rn4Pr41F8V8LLp3VsRKhQyUYrr25CdlJv
+2p6miYmizcr0JBqwoCxHW4TWbDNPhLss9yqPUxYrBOeEsQp8bsjmj0wrIT3gC8ed
+AdgEVY1+9AEEAL37L+v5AKOrFspzgpKj450XIelkLdkKlqqR7yrQZ+nZKZ9+4nWj
+xs/f+tJLwR9/XeK8YMktpvJkvGHzMz21Wz54iq8EfsTy6fRawfVkePxNAAZTcwf4
+DfCCVTpfEtJnVqoWWzy6elqbkgViLB346jLTUenm6cy8OhBfd5DAibfJABEBAAEA
+A/sE2qaqTlXsWKI/8Pycl5Bowp8MshET0xfvasQkIWgOSwyrtRe/LryVMiFb/zCD
+iAMTmIGWklKKLfW8QPUFth0LK8c02jIRvCRAc8lr3V+CGmTqxWCPsYWnHxIINc03
+wECMbFHLCAUlKelN/DJIKoI0LJJVvzYEy5xt9SvNBJiW6wIAzKgYNJNAgRvQOeb5
+MxKjCybYoUjFKOfdAaJkTwE0xuSaxap5ZUUfIADXT/C6SpbAfywIBFj8gYrwyPPo
+a4eGcwIA7aSTYyglPlzXc9AbfRh1jiIT4/QhUL1BBvtCVAkfbX1/x5llHCf64bJe
+/j15bBJeGzLAjMIxcSblP4/IYGG90wIA44bpOk4G8Smt3NfDYviixhHSVXXc+GUq
+woCV09mbSwpHNBek7Nec+c53MTRuoj2XPMWrYyeX3LIVDShlbaWWopiziJ8EGAEC
+AAkFAlWNfvQCGwwACgkQTtmeTooLM3pNSQP/eDZJ91HczYhKIKdIZ2egWmm5KJP5
+sVC8pmfl1i6ww5dqYvOJrCE8TtbYonGd5z/M6IXRa37Rax9c3aFOYZ/hoBobJPRa
+4Y9IF2HgUW2eDRNRFFaHmP8X3vE/rkQMWumNHb5c1bAVB9BAHdC+hBlFPhvRHYtk
+/Nhz7I3mDoPlCOk=
+=5aNq
+-----END PGP PRIVATE KEY BLOCK-----
Index: /trunk/test/test.sh
===================================================================
--- /trunk/test/test.sh	(revision 549)
+++ /trunk/test/test.sh	(revision 550)
@@ -154,4 +154,5 @@
     echo "  ${S}test.sh 12${E}  -- CL create DeltaDB" 
     echo "  ${S}test.sh 13${E}  -- CL create/verify partial DB" 
+    echo "  ${S}test.sh 14${E}  -- Signify signed files" 
 
     echo "  ${S}test.sh 20${E}  -- Test c/s init/check      (testrc_2.in)"
@@ -171,5 +172,5 @@
     echo "  (5) testext.sh     (6) testtimesrv.sh  (7) testrun_1b.sh  (8) testrun_1c.sh" 
     echo "  (9) testrun_1d.sh (10) testrun_1e.sh  (11) testrun_1f.sh (12) testrun_1g.sh" 
-    echo " (13) testrun_1h.sh"
+    echo " (13) testrun_1h.sh (14) testrun_1i.sh"
     echo " (20) testrun_2.sh  (21) testrun_2a.sh  (22) testrun_2b.sh (23) testrun_2c.sh"
     echo " (24) testrun_2d.sh (25) testrun_2e.sh  (26) testrun_2f.sh (27) testrun_2g.sh"
@@ -657,4 +658,10 @@
     exit $?
 fi
+if test x$1 = x14; then
+    . ${SCRIPTDIR}/testrun_1i.sh
+    testrun1i
+    print_summary
+    exit $?
+fi
 if test x$1 = x20; then
     . ${SCRIPTDIR}/testrun_2.sh 
@@ -736,4 +743,6 @@
     . ${SCRIPTDIR}/testrun_1h.sh
     let "TEST_MAX = TEST_MAX + MAXTEST" >/dev/null
+    . ${SCRIPTDIR}/testrun_1i.sh
+    let "TEST_MAX = TEST_MAX + MAXTEST" >/dev/null
     . ${SCRIPTDIR}/testrun_2.sh
     let "TEST_MAX = TEST_MAX + MAXTEST" >/dev/null
@@ -809,4 +818,8 @@
     MAXTEST=${TEST_MAX}; export MAXTEST
     testrun1h
+    #
+    . ${SCRIPTDIR}/testrun_1i.sh
+    MAXTEST=${TEST_MAX}; export MAXTEST
+    testrun1i
     #
     . ${SCRIPTDIR}/testrun_2.sh
Index: /trunk/test/test1i_samhain.pub
===================================================================
--- /trunk/test/test1i_samhain.pub	(revision 550)
+++ /trunk/test/test1i_samhain.pub	(revision 550)
@@ -0,0 +1,2 @@
+untrusted comment: signify public key
+RWRGHbBcvfnUvBA0DUrvkt5OIZzdOgD0X8mTn6wKd4UNOHp8mVL2pCKP
Index: /trunk/test/testrc_1i.dyn
===================================================================
--- /trunk/test/testrc_1i.dyn	(revision 550)
+++ /trunk/test/testrc_1i.dyn	(revision 550)
@@ -0,0 +1,40 @@
+untrusted comment: verify with samhain.pub
+RWRGHbBcvfnUvI+f5wRdzGBIpcVr3e3YJoB9f7ltII+sWwTpKBjfh60VkC0e/svAHFR03LIwALRz8CB70EokYYa3FVnmPgWv5Qg=
+
+[Attributes]
+file=/etc
+
+# not really logfiles, but almost guaranteed to exist
+[GrowingLogFiles]
+file=/etc/services
+file=/etc/hosts
+file=/etc/motd
+
+[EventSeverity]
+SeverityUser0=crit
+SeverityUser1=crit
+SeverityReadOnly=crit
+SeverityLogFiles=crit
+SeverityGrowingLogs=crit
+SeverityIgnoreNone=crit
+SeverityAttributes=crit
+SeverityIgnoreAll=warn
+SeverityFiles=notice
+SeverityDirs=info
+SeverityNames=warn
+
+[Log]
+MailSeverity=none
+LogSeverity=warn
+SyslogSeverity=none
+PrintSeverity=info
+
+[Misc]
+Daemon=no
+SetFilecheckTime=120
+SetRecursionLevel=10
+SetLoopTime=60
+ReportFullDetail = no
+ChecksumTest=check
+
+[EOF]
Index: /trunk/test/testrc_2.in.asc
===================================================================
--- /trunk/test/testrc_2.in.asc	(revision 550)
+++ /trunk/test/testrc_2.in.asc	(revision 550)
@@ -0,0 +1,216 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+NotDashEscaped: You need GnuPG to verify this message
+
+#####################################################################
+#
+# Configuration file template for samhain.
+#
+#####################################################################
+# 
+# -- empty lines and lines starting with '#' are ignored 
+# -- you can PGP clearsign this file -- samhain will check (if compiled
+#    with support) or otherwise ignore the signature
+# -- CHECK mail address
+#
+# To each log facility, you can assign a threshold severity. Only
+# reports with at least the threshold severity will be logged
+# to the respective facility (even further below).
+#
+#####################################################################
+#
+# SETUP for file system checking:
+# 
+# (i)   There are several policies, each has its own section. Put files
+#       into the section for the appropriate policy (see below).
+# (ii)  To each policy, you can assign a severity (further below).
+# (iii) To each log facility, you can assign a threshold severity. Only
+#       reports with at least the threshold severity will be logged
+#       to the respective facility (even further below).
+#
+#####################################################################
+
+
+[ReadOnly]
+#
+# for these files, only access time is ignored
+#
+# dir=/usr/bin
+# dir=/bin
+
+file = /var
+file = /bin
+file = /usr
+file = /tmp
+file = /etc
+
+# hopefully does not exist
+file=/etc/toodleedoo
+
+dir=1/usr
+
+[EventSeverity]
+#
+# Here you can assign severities to policy violations.
+# If this severity exceeds the treshold of a log facility (see below),
+# a policy violation will be logged to that facility.
+#
+# Severity for verification failures.
+#
+SeverityReadOnly=crit
+SeverityLogFiles=crit
+SeverityGrowingLogs=crit
+SeverityIgnoreNone=crit
+SeverityAttributes=crit
+#
+# We have a file in IgnoreAll that might or might not be present.
+# Setting the severity to 'info' prevents messages about deleted/new file.
+#
+SeverityIgnoreAll=info
+
+#
+# Files : file access problems
+# Dirs  : directory access problems
+# Names : suspect (non-printable) characters in a pathname
+#
+SeverityFiles=crit
+SeverityDirs=crit
+SeverityNames=warn
+
+[Log]
+#
+# Set threshold severity for log facilities
+# Values: debug, info, notice, warn, mark, err, crit, alert, none.
+# 'mark' is used for timestamps.
+#
+# By default, everything equal to and above the threshold is logged.
+# The specifiers '*', '!', and '=' are interpreted as  
+# 'all', 'all but', and 'only', respectively (like syslogd(8) does, 
+# at least on Linux). 
+# 
+# MailSeverity=*
+# MailSeverity=!warn
+# MailSeverity==crit
+#
+MailSeverity=none
+PrintSeverity=info
+#PRINTClass = "RUN FIL STAMP"
+LogSeverity=none
+SyslogSeverity=none
+ExportSeverity=none
+DatabaseSeverity=none
+
+#databaseseverity=info
+
+[Database]
+# setdbname=samhain
+# setdbtable=log
+setdbuser=samhain
+setdbpassword=samhain
+#AddToDBHash=log_msg
+# AddToDBHash=log_host
+UsePersistent = True
+
+[Utmp]
+#
+# 0 to switch off, 1 to activate
+#
+LoginCheckActive=1
+
+# Severity for logins, multiple logins, logouts
+# 
+SeverityLogin=info
+SeverityLoginMulti=warn
+SeverityLogout=info
+
+# interval for login/logout checks
+#
+LoginCheckInterval=60
+
+[Misc]
+#
+# whether to become a daemon process
+Daemon=no
+
+SetOutgoingIP = 127.0.0.1
+SetServerInterface = 127.0.0.1
+
+UseSeparateLogs=no
+
+SetUseSocket = yes
+SetSocketAllowUid=0
+SetSocketPassword=samhain
+
+SetClientFromAccept = yes
+
+SetUdpActive=no
+
+# the maximum time between client messages (seconds)
+# (this is a log server-only option; the default is 86400 sec = 1 day
+#
+# SetClientTimeLimit=1800
+
+UseClientSeverity = yes
+UseClientClass    = yes
+
+# Format for message headers
+#
+# MessageHeader="%S %T %F %L  "
+
+# priority for peer != address as notified by client
+# (lookup may fail on firewalled client)
+#
+# SeverityLookup = warn
+
+# time till next file check (seconds)
+SetFilecheckTime=600
+
+# Only highest-level (alert) reports will be mailed immediately,
+# others will be queued. Here you can define, when the queue will
+# be flushed (Note: the queue is automatically flushed after
+# completing a file check).
+#
+# maximum time till next mail (seconds)
+SetMailTime=86400
+
+# maximum number of queued mails
+SetMailNum=10
+
+# where to send mail to
+SetMailAddress=root@localhost
+
+# mail relay host
+# SetMailRelay=relay.yourdomain.de
+
+# The binary. Setting the path will allow
+# samhain to check for modifications between
+# startup and exit.
+#
+# SamhainPath=/usr/local/bin/samhain
+
+# where to get time from
+# SetTimeServer=www.yourdomain.de
+
+# where to export logs to
+SetLogServer=localhost
+
+# timer for time stamps
+SetLoopTime=10
+
+# trusted users (root and the effective user are always trusted)
+# TrustedUser=bin
+
+# whether to test signature of files (init/check/none)
+# - if 'none', then we have to decide this on the command line -
+#
+ChecksumTest=check
+
+
+[Clients]
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+
+iEYEARECAAYFAlUTGCcACgkQGq0myA9XH2zINACfQb/Wfa19OBbHVkw9uBNMB+lF
+cwUAnR0Geb+sFDcv7JsrrTjY8htjPHd2
+=7wXO
+-----END PGP SIGNATURE-----
Index: /trunk/test/testrun_1f.sh
===================================================================
--- /trunk/test/testrun_1f.sh	(revision 550)
+++ /trunk/test/testrun_1f.sh	(revision 550)
@@ -0,0 +1,292 @@
+#! /bin/sh
+
+#
+# Copyright Rainer Wichmann (2006)
+#
+# 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.
+#
+
+RCFILE="$PW_DIR/testrc_1.dyn";  export RCFILE
+LOGFILE="$PW_DIR/.samhain_log"; export LOGFILE
+
+# --enable-login-watch --enable-xml-log 
+# --enable-debug --enable-suidcheck --with-prelude
+
+BUILDOPTS="--quiet $TRUST --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file --enable-debug --with-gpg=/usr/bin/gpg --with-keyid=0x8A0B337A  --with-fp=DCCBBB6625591ECE2B8F3AC94ED99E4E8A0B337A"
+export BUILDOPTS
+
+BASE="${PW_DIR}/testrun_testdata"; export BASE
+TDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c"; export TDIRS
+TFILES="x y z"; export TFILES
+
+###########################################################
+#
+# ---- [Define tests here] ----
+#
+
+# 1 for testing new tests
+testrun1_setup=0
+
+MAXTEST=17; export MAXTEST
+
+TESTPOLICY_17="
+[ReadOnly]
+dir=${BASE}
+"
+mod_testdata_17 () {
+    one_sec_sleep
+    rm "${BASE}/a/a/c/x"   # delete 
+}
+
+TESTPOLICY_16="
+[ReadOnly]
+dir=${BASE}
+"
+mod_testdata_16 () {
+    one_sec_sleep
+    echo "foobar" > "${BASE}/foo"   # new 
+}
+
+prep_sign_file ()
+{
+    scripts/samhainadmin.pl -s ./test/gnupg/ -m R $1 >/dev/null
+    scripts/samhainadmin.pl -s ./test/gnupg/ -k 8A0B337A -m E $1 >/dev/null
+}
+
+
+run_check_CLverify ()
+{
+    if [ "x$1" = "x"  ]; then
+	logsev=debug
+    else
+	logsev=$1
+    fi
+    if test -f ./.samhain_file; then
+	mv ./.samhain_file ./.samhain_file_clverify
+	if [ $? -ne 0 ]; then
+	    [ -z "$quiet" ]   && log_msg_fail  "mv ./.samhain_file ...";
+	    return 1
+	fi
+    else
+	[ -z "$quiet" ]   && log_msg_fail  "test -f ./.samhain_file ...";
+	return 1
+    fi
+
+    rm -f test_log_valgrind
+
+    ${VALGRIND} ./samhain -p =err --verify-database ./.samhain_file_clverify 2>>test_log_valgrind
+ 
+    if test x$? = x0; then
+	if [ "x$2" != "xnullok"  ]; then
+	    [ -z "$quiet" ]   && log_msg_fail  "check (1)...";
+	    return 1
+	fi
+    else
+	if [ "x$2" = "xnullok"  ]; then
+	    [ -z "$quiet" ]   && log_msg_fail  "check (1)...";
+	    return 1
+	fi
+    fi
+
+    LL=`wc -l test_log_valgrind | awk '{ print $1; }'`
+    if ! test x$LL = x0; then
+	[ -z "$quiet" ]   && log_msg_fail  "check (2)...";
+	[ -z "$quiet" ]   && cat test_log_valgrind
+	return 1
+    fi
+    
+    [ -z "$verbose" ] || log_msg_ok    "check...";
+}
+
+run_update_CLverify ()
+{
+    if test -f ./.samhain_file_clverify; then
+	mv ./.samhain_file_clverify ./.samhain_file
+	if [ $? -ne 0 ]; then
+	    [ -z "$quiet" ]   && log_msg_fail  "mv ./.samhain_file_clverify ...";
+	    return 1
+	fi
+    else
+	[ -z "$quiet" ]   && log_msg_fail  "test -f ./.samhain_file_clverify ...";
+	return 1
+    fi
+
+    ${VALGRIND} ./samhain -t update -p none -l debug 2>>test_log_valgrind
+
+    if test x$? = x0; then
+	[ -z "$verbose" ] || log_msg_ok    "update...";
+    else
+	[ -z "$quiet" ]   && log_msg_fail  "update...";
+	return 1
+    fi
+}
+
+run_check_after_update_CLverify ()
+{
+    rm -rf $LOGFILE
+
+    run_check_CLverify debug nullok
+}
+
+testrun_internal_CLverify ()
+{
+	[ -z "$verbose" ] || echo Working directory: $PW_DIR
+	[ -z "$verbose" ] || { echo MAKE is $MAKE; echo; }
+
+	#
+	# test standalone compilation
+	#
+	[ -z "$verbose" ] || { echo; echo "${S}Building standalone agent${E}"; echo; }
+
+	if test -r "Makefile"; then
+		$MAKE distclean >/dev/null 
+	fi
+
+	${TOP_SRCDIR}/configure ${BUILDOPTS} 
+
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE  >/dev/null 2>>test_log
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	[ -z "$verbose" ] || { echo; echo "${S}Running test suite${E}"; echo; }
+
+	tcount=1
+	POLICY=`eval echo '"$'"TESTPOLICY_$tcount"'"'`
+
+	until [ -z "$POLICY" ]
+	do
+	  prep_init
+	  check_err $? ${tcount}; errval=$?
+	  if [ $errval -eq 0 ]; then
+	      prep_testdata
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      prep_testpolicy   ${tcount}
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      prep_sign_file  "${RCFILE}"
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      run_init
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      prep_sign_file  ./.samhain_file
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      eval mod_testdata_${tcount}
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      run_check_CLverify
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $testrun1_setup -eq 0 ]; then
+	      if [ $errval -eq 0 ]; then
+		  prep_sign_file  "${RCFILE}"
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	      if [ $errval -eq 0 ]; then
+		  run_update_CLverify
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	      if [ $errval -eq 0 ]; then
+		  prep_sign_file  ./.samhain_file
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	      if [ $errval -eq 0 ]; then
+		  run_check_after_update_CLverify
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	  fi
+	  #
+	  if [ $errval -eq 0 ]; then
+	      [ -z "$quiet" ] && log_ok ${tcount} ${MAXTEST};
+	  fi
+	  #
+	  let "tcount = tcount + 1" >/dev/null
+	  #
+	  if [ $tcount -eq 10 ]; then
+	      if [ -z "$doall" ]; then
+		  log_skip 10 $MAXTEST 'ACL/SELinux test (or use --really-all)'
+		  log_skip 11 $MAXTEST 'ACL/SELinux test (or use --really-all)'
+		  let "tcount = tcount + 2" >/dev/null
+	      else
+		  # 'id -u' is posix
+		  #
+		  if test -f /usr/xpg4/bin/id
+		  then
+		      my_uid=`/usr/xpg4/bin/id -u`
+		  else
+		      my_uid=`id -u`
+		  fi
+		  #
+		  if [ ${my_uid} -ne 0 ]; then
+		      log_skip 10 $MAXTEST 'ACL/SELinux test (you are not root)'
+		      log_skip 11 $MAXTEST 'ACL/SELinux test (you are not root)'
+		      let "tcount = tcount + 2" >/dev/null
+		  else
+
+		      SETFATTR=`find_path setfattr`
+		      if [ -z "$SETFATTR" ]; then
+			  log_skip 10 $MAXTEST 'ACL/SELinux test (setfattr not in path)'
+			  log_skip 11 $MAXTEST 'ACL/SELinux test (setfattr not in path)'
+			  let "tcount = tcount + 2" >/dev/null
+		      fi
+		  fi
+	      fi
+	  fi
+	  #
+	  POLICY=`eval echo '"$'"TESTPOLICY_$tcount"'"'`
+	done
+	    
+	return 0
+}
+
+testrun1f ()
+{
+    log_start "RUN CL Verify"
+    gpg --list-keys | grep 8A0B337A >/dev/null 2>&1
+    if [ $? -ne 0 ]; then
+	echo "You need to do 'gpg --import test/gnupg/public-key.asc' first"
+	for ff in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17; do
+	    log_skip $ff $MAXTEST 'CL verify'
+	done
+    else
+	testrun_internal_CLverify
+    fi
+    log_end "RUN CL Verify"
+    return 0
+}
+
+
+
Index: /trunk/test/testrun_1g.sh
===================================================================
--- /trunk/test/testrun_1g.sh	(revision 550)
+++ /trunk/test/testrun_1g.sh	(revision 550)
@@ -0,0 +1,114 @@
+#! /bin/sh
+
+#
+# Copyright Rainer Wichmann (2006)
+#
+# 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.
+#
+
+BUILDOPTS="--quiet $TRUST --enable-debug --enable-xml-log --enable-login-watch --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file"
+export BUILDOPTS
+
+MAXTEST=1; export MAXTEST
+
+testrun_deltadb ()
+{
+    tcount=1
+
+    if test -r "Makefile"; then
+	$MAKE distclean >/dev/null 
+    fi
+    
+    ${TOP_SRCDIR}/configure ${BUILDOPTS} 
+    
+    if test x$? = x0; then
+	[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+	$MAKE  >/dev/null 2>>test_log
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok "make..."; 
+	else
+	    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+	    return 1
+	fi
+	
+    else
+	[ -z "$quiet" ] &&       log_msg_fail "configure...";
+	return 1
+    fi
+
+    prep_init
+    check_err $? ${tcount}; errval=$?
+
+    if [ $errval -eq 0 ]; then
+	prep_testdata
+	check_err $? ${tcount}; errval=$?
+    fi
+    if [ $errval -eq 0 ]; then
+	prep_testpolicy   1
+	check_err $? ${tcount}; errval=$?
+    fi
+
+    rm "${BASE}/a/a/b/x"
+    rm -f file.*.*-*-*-*-*
+
+    ./samhain --create-database=./tmp_list_file
+
+    check_err $? ${tcount}; errval=$?
+    if [ $errval -eq 0 ]; then
+	num=$( ./samhain -a -d file.*.*-*-*-*-* | grep "1970-01-01T00:00:00" >/dev/null | wc -l )
+	if [ $num -ne 1 ]; then
+	    [ -z "$verbose" ] || log_msg_ok "list...";
+	else
+	    [ -z "$quiet" ] &&       log_msg_fail "list...";
+	    log_fail ${tcount} ${MAXTEST};
+	fi
+    else
+	[ -z "$quiet" ] &&       log_msg_fail "create...";
+	log_fail ${tcount} ${MAXTEST};
+    fi
+
+    if [ $errval -eq 0 ]; then
+	./samhain --verify-database file.*.*-*-*-*-*
+    fi
+
+    check_err $? ${tcount}; errval=$?
+    if [ $errval -eq 0 ]; then
+	echo "o_O" > "${BASE}/a/a/b/y"
+	./samhain --verify-database file.*.*-*-*-*-*
+    fi
+    if [ $? -eq 0 ]; then
+	[ -z "$quiet" ] &&       log_msg_fail "detect modify...";
+	check_err 1 ${tcount}; errval=1
+    fi
+
+    if [ $errval -eq 0 ]; then
+	[ -z "$quiet" ] && log_ok ${tcount} ${MAXTEST};
+    fi
+
+    [ -z "$cleanup" ] || rm -f file.*.*-*-*-*-*
+    return 0
+}
+
+testrun1g ()
+{
+    log_start "RUN CL Create DeltaDB"
+
+    testrun_deltadb
+
+    log_end "RUN CL Create DeltaDB"
+    return 0
+}
+
Index: /trunk/test/testrun_1h.sh
===================================================================
--- /trunk/test/testrun_1h.sh	(revision 550)
+++ /trunk/test/testrun_1h.sh	(revision 550)
@@ -0,0 +1,305 @@
+#! /bin/sh
+
+#
+# Copyright Rainer Wichmann (2006)
+#
+# 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.
+#
+
+RCFILE="$PW_DIR/testrc_1.dyn";  export RCFILE
+LOGFILE="$PW_DIR/.samhain_log"; export LOGFILE
+
+# --enable-login-watch --enable-xml-log 
+# --enable-debug --enable-suidcheck --with-prelude
+
+BUILDOPTS="--quiet $TRUST --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file --enable-debug"
+export BUILDOPTS
+
+BASE="${PW_DIR}/testrun_testdata"; export BASE
+TDIRS="a b c a/a a/b a/c a/a/a a/a/b a/a/c a/a/a/a a/a/a/b a/a/a/c"; export TDIRS
+TFILES="x y z"; export TFILES
+TFILES_PART="c/miss c/add c/change c/leave"; export TFILES_PART
+
+###########################################################
+#
+# ---- [Define tests here] ----
+#
+
+# 1 for testing new tests
+testrun1_setup=0
+
+MAXTEST=5; export MAXTEST
+
+PARTIAL_OUTFILE=".samhain_file_partial"; export PARTIAL_OUTFILE
+PARTIAL_FILTER="c/create c/miss c/change c/leave"; export PARTIAL_FILTER
+
+TEST_PART_POLICY_1="
+[ReadOnly]
+dir=${BASE}
+"
+mod_testdata_partial_1 () {
+    one_sec_sleep
+    rm "${BASE}/a/a/c/x"   # delete 
+}
+EXPECT_1="nullok"
+
+TEST_PART_POLICY_2="
+[ReadOnly]
+dir=${BASE}
+"
+mod_testdata_partial_2 () {
+    one_sec_sleep
+    echo "foobar" > "${BASE}/foo"   # new 
+}
+EXPECT_2="nullok"
+
+TEST_PART_POLICY_3="
+[ReadOnly]
+dir=${BASE}
+"
+mod_testdata_partial_3 () {
+    one_sec_sleep
+    rm -f "${BASE}/c/miss"
+}
+EXPECT_3=""
+
+TEST_PART_POLICY_4="
+[ReadOnly]
+dir=${BASE}
+"
+mod_testdata_partial_4 () {
+    one_sec_sleep
+    echo foo >"${BASE}/c/create"
+}
+EXPECT_4=""
+
+TEST_PART_POLICY_5="
+[ReadOnly]
+dir=${BASE}
+"
+mod_testdata_partial_5 () {
+    one_sec_sleep
+    echo toodledoo >"${BASE}/c/change"
+}
+EXPECT_5=""
+
+#
+# $2 == "nullok" means no mods should be detected,
+# else it is an error to detect no mods
+#
+run_check_partial_verify ()
+{
+    if [ "x$1" = "x"  ]; then
+	logsev=debug
+    else
+	logsev=$1
+    fi
+    if ! test -f ${PARTIAL_OUTFILE}; then
+	[ -z "$quiet" ]   && log_msg_fail  "missing ${PARTIAL_OUTFILE} ...";
+	return 1
+    fi
+
+    rm -f test_log_valgrind
+
+    ${VALGRIND} ./samhain -p =err --verify-database ${PARTIAL_OUTFILE} 2>>test_log_valgrind
+ 
+    if test x$? = x0; then
+	if [ "x$2" != "xnullok"  ]; then
+	    [ -z "$quiet" ]   && log_msg_fail  "check (1a)...";
+	    return 1
+	fi
+    else
+	if [ "x$2" = "xnullok"  ]; then
+	    [ -z "$quiet" ]   && log_msg_fail  "check (1b)...";
+	    return 1
+	fi
+    fi
+
+    LL=`wc -l test_log_valgrind | awk '{ print $1; }'`
+    if ! test x$LL = x0; then
+	[ -z "$quiet" ]   && log_msg_fail  "check (2)...";
+	[ -z "$quiet" ]   && cat test_log_valgrind
+	return 1
+    fi
+    
+    [ -z "$verbose" ] || log_msg_ok    "check...";
+}
+
+run_update_partial_verify ()
+{
+    ${VALGRIND} ./samhain -t update -p none -l debug 2>>test_log_valgrind
+
+    if test x$? = x0; then
+	[ -z "$verbose" ] || log_msg_ok    "update...";
+    else
+	[ -z "$quiet" ]   && log_msg_fail  "update...";
+	return 1
+    fi
+}
+
+run_check_after_update_partial ()
+{
+    rm -rf $LOGFILE
+
+    run_check_partial_verify debug nullok
+}
+
+create_partial ()
+{
+    echo "${BASE}/c" > test_filter.txt
+    for ff in ${TFILES_PART}; do
+	echo "${BASE}/${ff}" >> test_filter.txt
+    done
+
+    ./samhain -o "${PARTIAL_OUTFILE}" --binary --list-filter=test_filter.txt --list-database=./.samhain_file
+
+    if test x$? = x0; then
+	[ -z "$verbose" ] || log_msg_ok    "create partial DB...";
+    else
+	[ -z "$quiet" ]   && log_msg_fail  "create partial DB...";
+	return 1
+    fi
+
+    if test -f "${PARTIAL_OUTFILE}"; then
+	[ -z "$verbose" ] || log_msg_ok    "partial DB exists...";
+    else
+	[ -z "$quiet" ]   && log_msg_fail  "partial DB exists...";
+	return 1
+    fi
+    rm -f test_filter.txt
+}
+
+prep_partial_testpolicy ()
+{
+    test -f "${RCFILE}" || touch "${RCFILE}"
+    eval echo '"$'"TEST_PART_POLICY_$1"'"' >>"${RCFILE}"
+}
+
+prep_testdata_partial ()
+{
+    prep_testdata
+    if test x$? = x0; then
+	touch "${BASE}/c/miss"
+	touch "${BASE}/c/change"
+	touch "${BASE}/c/leave"
+    else
+	return 1
+    fi
+}
+
+testrun_internal_partial_verify ()
+{
+	[ -z "$verbose" ] || echo Working directory: $PW_DIR
+	[ -z "$verbose" ] || { echo MAKE is $MAKE; echo; }
+
+	#
+	# test standalone compilation
+	#
+	[ -z "$verbose" ] || { echo; echo "${S}Building standalone agent${E}"; echo; }
+
+	if test -r "Makefile"; then
+		$MAKE distclean >/dev/null 
+	fi
+
+	${TOP_SRCDIR}/configure ${BUILDOPTS} 
+
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE  >/dev/null 2>>test_log
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	[ -z "$verbose" ] || { echo; echo "${S}Running test suite${E}"; echo; }
+
+	tcount=1
+	POLICY=`eval echo '"$'"TEST_PART_POLICY_$tcount"'"'`
+
+	until [ -z "$POLICY" ]
+	do
+	  prep_init
+	  check_err $? ${tcount}; errval=$?
+	  if [ $errval -eq 0 ]; then
+	      prep_testdata_partial
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      prep_partial_testpolicy   ${tcount}
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      run_init
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      create_partial
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      eval mod_testdata_partial_${tcount}
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $errval -eq 0 ]; then
+	      arg2=`eval echo '"$'"EXPECT_$tcount"'"'`
+	      run_check_partial_verify debug $arg2
+	      check_err $? ${tcount}; errval=$?
+	  fi
+	  if [ $testrun1_setup -eq 0 ]; then
+	      if [ $errval -eq 0 ]; then
+		  run_update_partial_verify
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	      if [ $errval -eq 0 ]; then
+		  create_partial
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	      if [ $errval -eq 0 ]; then
+		  run_check_after_update_partial
+		  check_err $? ${tcount}; errval=$?
+	      fi
+	  fi
+	  #
+	  if [ $errval -eq 0 ]; then
+	      [ -z "$quiet" ] && log_ok ${tcount} ${MAXTEST};
+	  fi
+	  #
+	  let "tcount = tcount + 1" >/dev/null
+	  #
+	  POLICY=`eval echo '"$'"TEST_PART_POLICY_$tcount"'"'`
+	done
+	    
+	return 0
+}
+
+testrun1h ()
+{
+    log_start "RUN CL Partial DB Verify"
+    testrun_internal_partial_verify
+    log_end "RUN CL Partial DB Verify"
+    return 0
+}
+
+
+
Index: /trunk/test/testrun_1i.sh
===================================================================
--- /trunk/test/testrun_1i.sh	(revision 550)
+++ /trunk/test/testrun_1i.sh	(revision 550)
@@ -0,0 +1,322 @@
+#! /bin/sh
+
+#
+# Copyright Rainer Wichmann (2006)
+#
+# 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.
+#
+
+MAXTEST=4; export MAXTEST
+LOGFILE="$PW_DIR/.samhain_log"; export LOGFILE
+RCFILE="$PW_DIR/testrc_1.dyn";  export RCFILE
+
+testrun1b_modrc ()
+{
+        ORIGINAL="\[EOF\]"
+        REPLACEMENT="\[PortCheck\]"
+        ex -s $RCFILE <<EOF
+%s/$ORIGINAL/$REPLACEMENT/g
+wq
+EOF
+
+        echo "PortCheckActive = yes" >>"$RCFILE"
+        echo "PortCheckInterface = 127.0.0.1" >>"$RCFILE"
+}
+
+testrun1b_internal ()
+{
+	BUILDOPTS="$1"
+	#
+	# test standalone compilation
+	#
+	[ -z "$verbose" ] || { echo; echo "${S}Building standalone agent${E}"; echo; }
+	#
+	if test -r "Makefile"; then
+		$MAKE distclean >/dev/null >&1
+	fi
+	#
+	# Bootstrapping
+	#
+	${TOP_SRCDIR}/configure >/dev/null 2>/dev/null
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure (bootstrap)..."; 
+		$MAKE  > /dev/null 2>&1
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make (bootstrap)..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make (bootstrap)..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure (bootstrap)...";
+		return 1
+	fi
+	#
+	#
+	${TOP_SRCDIR}/configure ${BUILDOPTS} 2>/dev/null
+	#
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE  > /dev/null 2>&1
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	cp ${SCRIPTDIR}/testrc_1i.dyn "$RCFILE"
+	
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "copy signed config file...";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "copy signed config file...";
+	    return 1
+	fi
+
+	if test "x$2" = "x"; then
+	    :
+	else
+	    CONVERT="$2"
+	    if test -f "${TOP_SRCDIR}/stealth_template.jpg"; then
+		[ -z "$verbose" ] || log_msg_ok "convert..."
+		"${CONVERT}" +compress "${TOP_SRCDIR}/stealth_template.jpg" stealth_template.ps >/dev/null
+	    else
+		[ -z "$quiet" ]   && log_msg_fail  "cannot find file stealth_template.jpg"
+		return 1
+	    fi
+	    if [ $? -ne 0 ]; then
+		[ -z "$quiet" ]   && log_msg_fail  "${CONVERT} +compress ${TOP_SRCDIR}/stealth_template.jpg stealth_template.ps";
+		return 1
+	    fi
+
+	    [ -z "$verbose" ] || log_msg_ok "hide..."
+	    ./samhain_stealth -s stealth_template.ps "$RCFILE" >/dev/null
+	    if [ $? -ne 0 ]; then
+		[ -z "$quiet" ]   && log_msg_fail  "${CONVERT} +compress ${TOP_SRCDIR}/stealth_template.jpg stealth_template.ps";
+		return 1
+	    fi
+
+	    mv -f stealth_template.ps "$RCFILE"
+	    if [ $? -ne 0 ]; then
+		[ -z "$quiet" ]   && log_msg_fail  "mv -f stealth_template.ps $RCFILE";
+		return 1
+	    fi
+
+	fi
+
+	rm -f ./.samhain_file
+	rm -f ./.samhain_log
+	rm -f ./.samhain_lock
+
+	./samhain -t init -p none -l info
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "init...";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "init...";
+	    return 1
+	fi
+
+	cp ${SCRIPTDIR}/test1i_file.sig $PW_DIR/.samhain_file
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "copy signed database file...";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "copy signed database file...";
+	    return 1
+	fi
+}
+
+testrun1b_nogpg ()
+{
+	BUILDOPTS="$1"
+	#
+	# test standalone compilation
+	#
+	[ -z "$verbose" ] || { echo; echo "${S}Building standalone agent${E}"; echo; }
+	#
+	if test -r "Makefile"; then
+		$MAKE distclean >/dev/null >&1
+	fi
+
+	${TOP_SRCDIR}/configure ${BUILDOPTS} 2>/dev/null 
+        #
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE  > /dev/null 2>&1
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	rm -f ./.samhain_file
+	rm -f ./.samhain_log
+	rm -f ./.samhain_lock
+
+	cp "${SCRIPTDIR}/testrc_1" "${RCFILE}"
+
+	if test "x$2" = "xmodrc"; then
+	    [ -z "$verbose" ] || log_msg_ok    "mod rc...";
+	    testrun1b_modrc
+	fi
+
+	./samhain -t init -p none -l info
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "init...";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "init...";
+	    return 1
+	fi
+
+}
+
+do_test_1b () {
+
+    ./samhain -t check -p none -l info
+    
+    if test x$? = x0; then
+	./samhain -j -L $LOGFILE >"${LOGFILE}.tmp" && mv "${LOGFILE}.tmp" "${LOGFILE}"
+	if [ $? -ne 0 ]; then
+	    [ -z "$quiet" ]   && log_msg_fail  "mv logfile...";
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "check...";
+    else
+	[ -z "$quiet" ]   && log_msg_fail  "check...";
+	return 1
+    fi
+    #
+    tmp=`egrep "Checking.*/etc(>|\")" $LOGFILE 2>/dev/null | wc -l`
+    if [ $tmp -ne 2 ]; then
+	[ -z "$verbose" ] || log_msg_fail "/etc";
+	return 1
+    fi
+    tmp=`egrep "Checking.*(>|\")" $LOGFILE 2>/dev/null | wc -l`
+    if [ $tmp -ne 10 ]; then
+	[ -z "$verbose" ] || log_msg_fail "checking";
+	return 1
+    fi
+    egrep "ADDED" $LOGFILE >/dev/null 2>&1
+    if [ $? -eq 0 ]; then
+	[ -z "$verbose" ] || log_msg_fail "init was incomplete";
+	return 1
+    fi
+    #
+    return 0
+}
+
+testrun1i ()
+{
+    log_start "RUN STANDALONE W/STEALTH W/SIGNIFY"
+    SIGNIFY=`find_path signify-openbsd`
+    if [ -z "$SIGNIFY" ]; then
+	SIGNIFY=`find_path signify`
+    fi
+    if [ -z "$SIGNIFY" ]; then
+	log_skip 1 $MAXTEST 'gpg not found in $PATH'
+	log_skip 2 $MAXTEST 'gpg not found in $PATH'
+	log_skip 3 $MAXTEST 'gpg not found in $PATH'
+	log_skip 4 $MAXTEST 'gpg not found in $PATH'
+    else
+	eval "ls ~/.signify/samhain.pub >/dev/null 2>/dev/null"
+	if [ $? -ne 0 ]; then
+	    log_skip 1 $MAXTEST 'public key ~/.signify/samhain.pub not present'
+	    log_skip 2 $MAXTEST 'public key ~/.signify/samhain.pub not present'
+	    log_skip 3 $MAXTEST 'public key ~/.signify/samhain.pub not present'
+	    log_skip 4 $MAXTEST 'public key ~/.signify/samhain.pub not present'
+	else
+	    #
+	    # -------------  first test -------------
+	    #
+	    BUILDOPTS="--quiet $TRUST --enable-debug --with-signify=${SIGNIFY} --enable-micro-stealth=137 --enable-login-watch --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE  --with-log-file=$PW_DIR/.samhain_log --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file"
+	    testrun1b_internal "${BUILDOPTS}" 
+	    do_test_1b
+	    if [ $? -eq 0 ]; then
+		log_ok   1 $MAXTEST 'signify signed config/database files'
+	    else
+		log_fail 1 $MAXTEST 'signify signed config/database files'
+	    fi
+
+
+	    #
+	    # -------------  second test -------------
+	    #
+	    BUILDOPTS="--quiet $TRUST --enable-debug --with-signify=${SIGNIFY} --with-checksum --enable-micro-stealth=137 --enable-login-watch --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE  --with-log-file=$PW_DIR/.samhain_log --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file"
+	    testrun1b_internal "${BUILDOPTS}" 
+	    do_test_1b
+	    if [ $? -eq 0 ]; then
+		log_ok   2 $MAXTEST 'signify signed config/database files'
+	    else
+		log_fail 2 $MAXTEST 'signify signed config/database files'
+	    fi
+
+
+	    #
+	    # -------------  third test -------------
+	    #
+	    BUILDOPTS="--quiet $TRUST --enable-debug --with-signify=${SIGNIFY} --with-checksum --with-pubkey-checksum=62F3EAE3CD9BA8849015060750908790B6326015A20AC0DA --enable-micro-stealth=137 --enable-login-watch --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE  --with-log-file=$PW_DIR/.samhain_log --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file"
+	    testrun1b_internal "${BUILDOPTS}" 
+	    do_test_1b
+	    if [ $? -eq 0 ]; then
+		log_ok   3 $MAXTEST 'signify signed config/database files'
+	    else
+		log_fail 3 $MAXTEST 'signify signed config/database files'
+	    fi
+
+
+	    #
+	    # -------------  fourth test -------------
+	    #
+	    PRECONV=`find_path convert`
+	    "${PRECONV}" --help | grep  ImageMagick >/dev/null 2>&1 && \
+ 		CONVERT="${PRECONV}"
+
+	    if [ -z "$CONVERT" ]; then
+		log_skip 2 $MAXTEST 'ImageMagick convert not found in $PATH'
+	    else
+		BUILDOPTS="--quiet $TRUST --enable-debug --with-signify=${SIGNIFY} --with-checksum --enable-stealth=137 --enable-login-watch --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE  --with-log-file=$PW_DIR/.samhain_log --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file"
+		testrun1b_internal "${BUILDOPTS}" "$CONVERT"
+		do_test_1b
+		if [ $? -eq 0 ]; then
+		    log_ok   4 $MAXTEST 'signify signed config/database files'
+		else
+		    log_fail 4 $MAXTEST 'signify signed config/database files'
+		fi
+	    fi
+
+	fi
+    fi
+    log_end "RUN STANDALONE W/STEALTH W/SIGNIFY"
+    return 0
+}
+
Index: /trunk/test/testrun_2e.sh
===================================================================
--- /trunk/test/testrun_2e.sh	(revision 550)
+++ /trunk/test/testrun_2e.sh	(revision 550)
@@ -0,0 +1,299 @@
+#! /bin/sh
+
+#
+# Copyright Rainer Wichmann (2006)
+#
+# 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.
+#
+
+LOGFILE="$PW_DIR/.samhain_log"; export LOGFILE
+RCFILE="$PW_DIR/testrc_2";  export RCFILE
+
+SERVER_BUILDOPTS="--quiet  $TRUST --enable-network=server --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=REQ_FROM_SERVER$PW_DIR/testrc_2 --with-data-file=REQ_FROM_SERVER$PW_DIR/.samhain_file --with-logserver=${SH_LOCALHOST}  --with-log-file=$PW_DIR/.samhain_log --with-pid-file=$PW_DIR/.samhain_lock --enable-debug=gdb"; export SERVER_BUILDOPTS
+
+CLIENT_BUILDOPTS="--quiet  $TRUST --enable-network=client --enable-srp --prefix=$PW_DIR --with-tmp-dir=$PW_DIR --localstatedir=$PW_DIR --with-config-file=REQ_FROM_SERVER$RCFILE --with-data-file=REQ_FROM_SERVER$PW_DIR/.samhain_file  --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --enable-debug"; export CLIENT_BUILDOPTS
+
+do_test_2_e () {
+
+	[ -z "$verbose" ] || { 
+	    echo; 
+	    echo "${S}Start Server${E}: ./yule -l info -p none &"; 
+	    echo; 
+	}
+	rm -f test_log_valgrind
+
+ 	# SetSocketAllowUid=$(id -u)
+	#
+	if test -f /usr/xpg4/bin/id; then
+	    MY_ID=$(/usr/xpg4/bin/id -u)
+	else
+	    MY_ID=$(id -u)
+	fi
+	#
+	sed -i -e "s/SetSocketAllowUid=0/SetSocketAllowUid=${MY_ID}/g" $RCFILE
+
+	# Start server
+	#
+	${VALGRIND} ./yule -l info -p none >/dev/null 2>>test_log_valgrind &
+	PROC_Y=$!
+	five_sec_sleep
+
+	./yulectl -c LIST >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (1)";
+	    kill $PROC_Y
+	    return 1
+	fi	
+	NR=$( ./yulectl -c LIST | wc -l )
+	if [ $NR -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (2)";
+	    kill $PROC_Y
+	    return 1
+	fi
+
+	./yulectl -c SCAN localhost.localdomain
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c SCAN";
+	    kill $PROC_Y
+	    return 1
+	fi
+
+	UUID=$(uuidgen)
+	./yulectl -c DELTA:$UUID localhost.localdomain
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c DELTA:$UUID";
+	    kill $PROC_Y
+	    return 1
+	fi
+
+	./yulectl -c RELOAD localhost.localdomain
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c RELOAD";
+	    kill $PROC_Y
+	    return 1
+	fi
+
+	./yulectl -c LIST >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (3)";
+	    kill $PROC_Y
+	    return 1
+	fi	
+	NR=$( ./yulectl -c LIST | wc -l )
+	if [ $NR -ne 3 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (4)";
+	    kill $PROC_Y
+	    return 1
+	fi
+	
+	{ ./yulectl -c LIST | head -n 1 | grep SCAN; } >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (5)";
+	    kill $PROC_Y
+	    return 1
+	fi	
+	{ ./yulectl -c LIST | tail -n 1 | grep RELOAD; } >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (6)";
+	    kill $PROC_Y
+	    return 1
+	fi	
+	{ ./yulectl -c LIST | tail -n 2 | head -n 1| grep "DELTA:$UUID"; } >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (7)";
+	    kill $PROC_Y
+	    return 1
+	fi
+
+	./yulectl -c CANCEL localhost.localdomain
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c CANCEL";
+	    kill $PROC_Y
+	    return 1
+	fi
+	
+	./yulectl -c LIST >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (8)";
+	    kill $PROC_Y
+	    return 1
+	fi	
+	NR=$( ./yulectl -c LIST | wc -l )
+	if [ $NR -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "./yulectl -c LIST (9)";
+	    kill $PROC_Y
+	    return 1
+	fi
+
+	kill $PROC_Y
+	return 0
+}
+
+testrun2e_internal ()
+{
+        [ -z "$verbose" ] || { 
+	    echo; 
+	    echo Working directory: $PW_DIR; echo MAKE is $MAKE; 
+	    echo; 
+	}
+	#
+	#
+	[ -z "$verbose" ] || { echo; echo "${S}Building client and server${E}"; echo; }
+	#
+	if test -r "Makefile"; then
+		$MAKE distclean
+	fi
+	#
+	${TOP_SRCDIR}/configure ${CLIENT_BUILDOPTS}
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE > /dev/null 2>>test_log
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	# save binary and build server
+	#
+	cp samhain samhain.build || return 1
+	$MAKE clean >/dev/null || return 1
+
+	${TOP_SRCDIR}/configure ${SERVER_BUILDOPTS}
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE  > /dev/null 2>>test_log
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+
+	#####################################################################
+	#
+	#
+	rm -f ./.samhain_file
+	rm -f ./.samhain_log
+	rm -f ./.samhain_lock
+	rm -f ./rc.${SH_LOCALHOST}
+	rm -f ./file.${SH_LOCALHOST}
+	rm -f  "./rc.${ALTHOST}"
+	rm -f  "./file.${ALTHOST}"
+
+	cp ${SCRIPTDIR}/testrc_2.in testrc_2
+
+	./samhain.build -t init -p none
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "init...";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "init...";
+	    return 1
+	fi
+
+	# Create a password
+
+	SHPW=`./yule -G`
+	if test x"$SHPW" = x; then
+	    [ -z "$quiet" ]   && log_msg_fail  "password not generated -- aborting"
+	    return 1
+	fi
+
+	# Set in client
+
+	./samhain_setpwd samhain.build new $SHPW >/dev/null
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "./samhain_setpwd samhain.build new $SHPW";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "./samhain_setpwd samhain.build new $SHPW";
+	    return 1
+	fi
+
+	mv samhain.build.new  samhain.new || return 1
+
+	rm -f ./.samhain_log*
+	rm -f ./.samhain_lock
+
+	SHCLT=`./yule -P $SHPW`
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "yule -P $SHPW";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "yule -P $SHPW";
+	    return 1
+	fi
+
+	SHCLT1=`echo "${SHCLT}"  | sed s%HOSTNAME%${SH_LOCALHOST}%`
+	AHOST=`find_hostname`
+	SHCLT2=`echo "${SHCLT}"  | sed s%HOSTNAME%${AHOST}%`
+	
+ 	echo $SHCLT1 >> testrc_2
+ 	echo $SHCLT2 >> testrc_2
+
+	cp    ./testrc_2       ./rc.${SH_LOCALHOST}
+	mv    ./.samhain_file  ./file.${SH_LOCALHOST}
+	chmod 644 ./rc.${SH_LOCALHOST}
+	chmod 644 ./file.${SH_LOCALHOST}
+
+	ALTHOST=`find_hostname`
+	cp    ./testrc_2       "./rc.${ALTHOST}"
+	cp    ./file.${SH_LOCALHOST} "./file.${ALTHOST}" 2>/dev/null
+	chmod 644 ./rc.${ALTHOST}
+	chmod 644 ./file.${ALTHOST}
+
+	echo $SHPW > ./testpw
+}
+
+MAXTEST=1; export MAXTEST
+
+testrun2e ()
+{
+    log_start "RUN SERVER W/YULECTL";
+    #
+    if [ x"$1" = x ]; then
+	[ -z "$quiet" ] && log_msg_fail "Missing hostname"
+    fi
+    #
+    SH_LOCALHOST=$1; export SH_LOCALHOST
+    #
+    testrun2e_internal
+    do_test_2_e
+    if [ $? -eq 0 ]; then
+	[ -z "$quiet" ] && log_ok   1 ${MAXTEST} "Server w/yulectl";
+    else
+	[ -z "$quiet" ] && log_fail 1 ${MAXTEST} "Server w/yulectl";
+    fi
+    ####### EXIT HERE FOR TESTING ######
+    #
+    #
+    log_end "RUN SERVER W/YULECTL"
+}
Index: /trunk/test/testrun_2f.sh
===================================================================
--- /trunk/test/testrun_2f.sh	(revision 550)
+++ /trunk/test/testrun_2f.sh	(revision 550)
@@ -0,0 +1,390 @@
+#! /bin/sh
+
+#
+# Copyright Rainer Wichmann (2006)
+#
+# 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.
+#
+
+LOGFILE="$PW_DIR/.samhain_log"; export LOGFILE
+RCFILE="$PW_DIR/testrc_2";  export RCFILE
+
+SERVER_BUILDOPTS="--quiet  $TRUST --enable-network=server --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=REQ_FROM_SERVER$PW_DIR/testrc_2 --with-data-file=REQ_FROM_SERVER$PW_DIR/.samhain_file --with-logserver=${SH_LOCALHOST}  --with-log-file=$PW_DIR/.samhain_log --with-pid-file=$PW_DIR/.samhain_lock --enable-debug=gdb"; export SERVER_BUILDOPTS
+
+CLIENT_BUILDOPTS="--quiet  $TRUST --enable-network=client --enable-srp --prefix=$PW_DIR --with-tmp-dir=$PW_DIR --localstatedir=$PW_DIR --with-config-file=REQ_FROM_SERVER$RCFILE --with-data-file=REQ_FROM_SERVER$PW_DIR/.samhain_file  --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --enable-debug"; export CLIENT_BUILDOPTS
+
+do_test_2_f () {
+
+	[ -z "$verbose" ] || { 
+	    echo; 
+	    echo "${S}Start Server${E}: ./yule -l info -p none &"; 
+	    echo; 
+	}
+	rm -f test_log_valgrind
+
+ 	# SetSocketAllowUid=$(id -u)
+	#
+	if test -f /usr/xpg4/bin/id; then
+	    MY_ID=$(/usr/xpg4/bin/id -u)
+	else
+	    MY_ID=$(id -u)
+	fi
+	#
+	sed -i -e "s/SetSocketAllowUid=0/SetSocketAllowUid=${MY_ID}/g" $RCFILE
+
+	# Start server
+	#
+	${VALGRIND} ./yule -l info -p none >/dev/null 2>>test_log_valgrind &
+	PROC_Y=$!
+	five_sec_sleep
+
+
+	[ -z "$verbose" ] || { 
+	    echo; 
+	    echo "${S}Start Client${E}: ./samhain.new -t check --foreground --forever .. &"; 
+	    echo; 
+	}
+	${VALGRIND} ./samhain.new -t check -D -p none -l none -e info --bind-address=127.0.0.1 --server-host=localhost >/dev/null 2>>test_log_valgrind 
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "starting samhain.new";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "starting samhain.new";
+	    kill $PROC_Y
+	    return 1
+	fi
+	five_sec_sleep
+	PROC_S=$(  ps aux | grep samhain.new | grep -v grep | awk '{ print $2; }' )
+
+	for ff in 1 2; do
+	    five_sec_sleep
+	done
+	egrep "File check completed" $LOGFILE >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	NR=$( egrep "File check completed" $LOGFILE | wc -l )
+	if [ $NR -ne 1 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (1)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	#
+	# >>> (1) Send SIGTTOU to force a second scan, 
+	# >>>      and verify that it was done
+	#
+	kill -TTOU $PROC_S
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Kill -TTOU";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	for ff in 1 2; do
+	    five_sec_sleep
+	done
+	NR=$( egrep "File check completed" $LOGFILE | wc -l )
+	if [ $NR -ne 2 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (2)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "sigttou";
+
+	NR=$( egrep "POLICY" $LOGFILE | wc -l )
+	if [ $NR -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (3)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	#
+	# >>> (2) Modify the file system
+	#
+
+	UUID=$(uuidgen)
+	mkdir /tmp/testrun_samhain/$UUID
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "mkdir";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	kill -TTOU $PROC_S
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Kill -TTOU (2)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	for ff in 1 2; do
+	    five_sec_sleep
+	done
+	NR=$( egrep "POLICY" $LOGFILE | wc -l )
+	if [ $NR -ne 1 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (4)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "/tmp/testrun_samhain modified";
+
+	kill $PROC_S; 
+	five_sec_sleep
+
+	rm -f ./.samhain_file
+	rm -f ./file.${SH_LOCALHOST} 
+	rm -f "./file.${ALTHOST}"
+
+	rm ./.samhain_log 
+	rm -f ./.samhain_lock
+
+	#
+	# >>> (3) Re-init the database 
+	#
+	./samhain.new -t init -p none
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "init (2) ..";
+	    kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "init (2) ..";
+
+	#
+	# >>> (4) Re-start Samhain with delay
+	#
+
+	sed --in-place -e 's/SetUdpActive=no/StartupLoadDelay=10/g' ./rc.${SH_LOCALHOST}
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "sed (1) ..";
+	    kill $PROC_Y;
+	    return 1
+	fi
+	sed --in-place -e 's/SetUdpActive=no/StartupLoadDelay=10/g' "./rc.${ALTHOST}"
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "sed (2) ..";
+	    kill $PROC_Y;
+	    return 1
+	fi
+
+	${VALGRIND} ./samhain.new -t check -D -p none -l none -e info --bind-address=127.0.0.1 --server-host=localhost >/dev/null 2>>test_log_valgrind 
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "starting samhain.new (2)";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "starting samhain.new (2)";
+	    kill $PROC_Y
+	    return 1
+	fi
+	five_sec_sleep
+	PROC_S=$(  ps aux | grep samhain.new | grep -v grep | awk '{ print $2; }' )
+
+	#
+	# >>> (5) Copy database to server after Samhain startup
+	# >>>     verifies that StartupLoadDelay works
+	#
+
+	if test -f ./.samhain_file; then
+	    mv ./.samhain_file ./file.${SH_LOCALHOST}
+	    chmod 644 ./file.${SH_LOCALHOST}
+
+	    ALTHOST=`find_hostname`
+	    cp    ./file.${SH_LOCALHOST} "./file.${ALTHOST}" 2>/dev/null
+	    chmod 644 ./file.${ALTHOST}
+	else
+	    [ -z "$verbose" ] || log_msg_fail "baseline file ..";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	for ff in 1 2 3; do
+	    five_sec_sleep
+	done
+	NR=$( egrep "File check completed" $LOGFILE | wc -l )
+	if [ $NR -ne 1 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (5)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "file check after delay";
+
+	NR=$( egrep "POLICY" $LOGFILE | wc -l )
+	if [ $NR -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (6)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	kill $PROC_S; 
+	kill $PROC_Y
+	return 0
+}
+
+testrun2f_internal ()
+{
+        [ -z "$verbose" ] || { 
+	    echo; 
+	    echo Working directory: $PW_DIR; echo MAKE is $MAKE; 
+	    echo; 
+	}
+	#
+	#
+	[ -z "$verbose" ] || { echo; echo "${S}Building client and server${E}"; echo; }
+	#
+	if test -r "Makefile"; then
+		$MAKE distclean
+	fi
+	#
+	${TOP_SRCDIR}/configure ${CLIENT_BUILDOPTS}
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE > /dev/null 2>>test_log
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	# save binary and build server
+	#
+	cp samhain samhain.build || return 1
+	$MAKE clean >/dev/null || return 1
+
+	${TOP_SRCDIR}/configure ${SERVER_BUILDOPTS}
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE  > /dev/null 2>>test_log
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+
+	#####################################################################
+	#
+	#
+	rm -f ./.samhain_file
+	rm -f ./.samhain_log
+	rm -f ./.samhain_lock
+	rm -f ./rc.${SH_LOCALHOST}
+	rm -f ./file.${SH_LOCALHOST}
+	rm -f  "./rc.${ALTHOST}"
+	rm -f  "./file.${ALTHOST}"
+
+	cp ${SCRIPTDIR}/testrc_2.in testrc_2
+
+	sed --in-place -e 's,file = /tmp,file = /tmp/testrun_samhain,g'  testrc_2
+	mkdir /tmp/testrun_samhain 2>/dev/null
+
+	./samhain.build -t init -p none
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "init...";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "init...";
+	    return 1
+	fi
+
+	# Create a password
+
+	SHPW=`./yule -G`
+	if test x"$SHPW" = x; then
+	    [ -z "$quiet" ]   && log_msg_fail  "password not generated -- aborting"
+	    return 1
+	fi
+
+	# Set in client
+
+	./samhain_setpwd samhain.build new $SHPW >/dev/null
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "./samhain_setpwd samhain.build new $SHPW";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "./samhain_setpwd samhain.build new $SHPW";
+	    return 1
+	fi
+
+	mv samhain.build.new  samhain.new || return 1
+
+	rm -f ./.samhain_log*
+	rm -f ./.samhain_lock
+
+	SHCLT=`./yule -P $SHPW`
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "yule -P $SHPW";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "yule -P $SHPW";
+	    return 1
+	fi
+
+	SHCLT1=`echo "${SHCLT}"  | sed s%HOSTNAME%${SH_LOCALHOST}%`
+	AHOST=`find_hostname`
+	SHCLT2=`echo "${SHCLT}"  | sed s%HOSTNAME%${AHOST}%`
+	
+ 	echo $SHCLT1 >> testrc_2
+ 	echo $SHCLT2 >> testrc_2
+
+	cp    ./testrc_2       ./rc.${SH_LOCALHOST}
+	mv    ./.samhain_file  ./file.${SH_LOCALHOST}
+	chmod 644 ./rc.${SH_LOCALHOST}
+	chmod 644 ./file.${SH_LOCALHOST}
+
+	ALTHOST=`find_hostname`
+	cp    ./testrc_2       "./rc.${ALTHOST}"
+	cp    ./file.${SH_LOCALHOST} "./file.${ALTHOST}" 2>/dev/null
+	chmod 644 ./rc.${ALTHOST}
+	chmod 644 ./file.${ALTHOST}
+
+	echo $SHPW > ./testpw
+}
+
+MAXTEST=1; export MAXTEST
+
+testrun2f ()
+{
+    log_start "RUN CLIENT/SERVER CASE ONE";
+    #
+    if [ x"$1" = x ]; then
+	[ -z "$quiet" ] && log_msg_fail "Missing hostname"
+    fi
+    #
+    SH_LOCALHOST=$1; export SH_LOCALHOST
+    #
+    testrun2f_internal
+    do_test_2_f
+    if [ $? -eq 0 ]; then
+	[ -z "$quiet" ] && log_ok   1 ${MAXTEST} "Case One Change Management Integration";
+    else
+	[ -z "$quiet" ] && log_fail 1 ${MAXTEST} "Case One Change Management Integration";
+    fi
+    #
+    log_end "RUN CLIENT/SERVER CASE ONE"
+}
Index: /trunk/test/testrun_2g.sh
===================================================================
--- /trunk/test/testrun_2g.sh	(revision 550)
+++ /trunk/test/testrun_2g.sh	(revision 550)
@@ -0,0 +1,826 @@
+#! /bin/sh
+
+#
+# Copyright Rainer Wichmann (2015)
+#
+# 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.
+#
+
+LOGFILE="$PW_DIR/.samhain_log"; export LOGFILE
+RCFILE="$PW_DIR/testrc_2";  export RCFILE
+
+SERVER_BUILDOPTS="--quiet  $TRUST --enable-network=server --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=REQ_FROM_SERVER$PW_DIR/testrc_2 --with-data-file=REQ_FROM_SERVER$PW_DIR/.samhain_file --with-logserver=${SH_LOCALHOST}  --with-log-file=$PW_DIR/.samhain_log --with-pid-file=$PW_DIR/.samhain_lock --enable-debug=gdb --enable-static"; export SERVER_BUILDOPTS
+
+CLIENT_BUILDOPTS="--quiet  $TRUST --enable-network=client --enable-srp --prefix=$PW_DIR --with-tmp-dir=$PW_DIR --localstatedir=$PW_DIR --with-config-file=REQ_FROM_SERVER$RCFILE --with-data-file=REQ_FROM_SERVER$PW_DIR/.samhain_file  --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --enable-static"; export CLIENT_BUILDOPTS
+
+TEST_DIRS="one two three four"
+TEST_FILES="change leave rmthis"
+BASE="/tmp/testrun_samhain"
+
+TEST_LIST="./tmp_list_file"
+
+ALTHOST=`find_hostname`
+
+PROC_S=0; export PROC_S
+PROC_Y=0; export PROC_Y
+
+mod_files ()
+{
+    rm -f "${TEST_LIST}"
+    touch "${TEST_LIST}"
+    #
+    for dd in ${TEST_DIRS}; do
+	echo "changed" > "${BASE}/$dd/change"
+	rm -f "${BASE}/$dd/rmthis"
+	echo "added" > "${BASE}/$dd/addedthis"
+	echo "${BASE}/$dd"           >> "${TEST_LIST}"
+	echo "${BASE}/$dd/change"    >> "${TEST_LIST}"
+	echo "${BASE}/$dd/rmthis"    >> "${TEST_LIST}"
+	echo "${BASE}/$dd/addedthis" >> "${TEST_LIST}"
+    done
+}
+
+do_test_2_g_yule_start () {
+
+	[ -z "$verbose" ] || { 
+	    echo; 
+	    echo "${S}Start Server${E}: ./yule -l info -p none &"; 
+	    echo; 
+	}
+	rm -f test_log_valgrind
+
+ 	# SetSocketAllowUid=$(id -u)
+	#
+	if test -f /usr/xpg4/bin/id; then
+	    MY_ID=$(/usr/xpg4/bin/id -u)
+	else
+	    MY_ID=$(id -u)
+	fi
+	#
+	sed -i -e "s/SetSocketAllowUid=0/SetSocketAllowUid=${MY_ID}/g" $RCFILE
+
+	# Start server
+	#
+	${VALGRIND} ./yule -l info -p none >/dev/null 2>>test_log_valgrind &
+	PROC_Y=$!
+	five_sec_sleep
+
+
+	[ -z "$verbose" ] || { 
+	    echo; 
+	    echo "${S}Start Client${E}: ./samhain.new -t check -D .. &"; 
+	    echo; 
+	}
+	${VALGRIND} ./samhain.new -t check -D -p none -l none -e info --bind-address=127.0.0.1 --server-host=localhost >/dev/null 2>>test_log_valgrind 
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "starting samhain.new";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "starting samhain.new";
+	    kill $PROC_Y
+	    return 1
+	fi
+	five_sec_sleep
+	PROC_S=$(  ps aux | grep samhain.new | grep -v grep | awk '{ print $2; }' | sort | head -n 1 )
+
+	for ff in 1 2; do
+	    five_sec_sleep
+	done
+	egrep "File check completed" $LOGFILE >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	NR=$( egrep "File check completed" $LOGFILE | wc -l )
+	if [ $NR -ne 1 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (1)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	return 0
+}
+
+do_test_2_g_two () {
+
+	#
+	# >>> Modify files
+	#
+	mod_files
+	#
+	if ! test -f ${TEST_LIST}; then
+	    [ -z "$verbose" ] || log_msg_fail "No file list created";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	#
+	#
+	# >>> Trigger a scan
+	#
+	kill -TTOU $PROC_S
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Kill -TTOU";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	for ff in 1 2 3; do
+	    five_sec_sleep
+	done
+	NR=$( egrep "File check completed" $LOGFILE | wc -l )
+	if [ $NR -ne 2 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (2)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "sigttou";
+
+	NR=$( egrep "POLICY" $LOGFILE | grep ReadOnly | wc -l )
+	if [ $NR -ne 8 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (ReadOnly)";  
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	NR=$( egrep "POLICY" $LOGFILE | grep ADDED | wc -l )
+	if [ $NR -ne 4 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (added)";  
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	NR=$( egrep "POLICY" $LOGFILE | grep MISSING | wc -l )
+	if [ $NR -ne 4 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (removed)";  
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	kill $PROC_S; 
+	kill $PROC_Y;
+	return 0
+}
+
+do_test_2_g_one () {
+
+	#
+	# >>> (1) Modify files, create DeltaDB from file list in ${TEST_LIST}
+	#
+	mod_files
+	#
+	if ! test -f ${TEST_LIST}; then
+	    [ -z "$verbose" ] || log_msg_fail "No file list created";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	#
+	./samhain.new --outfile ./file.delta --create-database "${TEST_LIST}"
+	#
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Create DeltaDB";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	if ! test -f ./file.delta; then
+	    [ -z "$verbose" ] || log_msg_fail "No DeltaDB created";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	#
+	# >>> (2) Copy to server and tag with a UUID
+	#
+	UUID=$(uuidgen)
+	mv ./file.delta file.${SH_LOCALHOST}.${UUID}
+	cp file.${SH_LOCALHOST}.${UUID} "./file.${ALTHOST}.${UUID}"
+	
+	#
+	# >>> (3) Tell client to load delta database.
+	# >>>     testrc_2: timestamps every 10 sec
+	#
+	grep '^SetLoopTime=10$' rc.${SH_LOCALHOST} >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "SetLoopTime != 10 in rc.${SH_LOCALHOST}";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	grep '^SetLoopTime=10$' rc.${ALTHOST} >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "SetLoopTime != 10 in rc.${ALTHOST}";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	./yulectl -c "DELTA:${UUID}" ${SH_LOCALHOST}
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "yulectl (1)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	./yulectl -c "DELTA:${UUID}" ${ALTHOST}
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "yulectl (2)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	NR=$( ./yulectl -c LIST | grep ${UUID} | grep -v grep | wc -l )
+	if [ $NR -ne 2 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "yulectl (3)";
+	    [ -z "$verbose" ] || ./yulectl -c LIST
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	# Wait and verify that command has been sent
+	#
+	for tt in 1 2 3 4; do
+	    five_sec_sleep
+	done
+	#
+	NR=$( ./yulectl -c LIST | grep ${UUID} | grep -v grep | wc -l )
+	if [ $NR -ne 1 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "yulectl (4)";
+	    [ -z "$verbose" ] || ./yulectl -c LISTALL
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	#
+	# >>> (4) Trigger a scan
+	#
+	kill -TTOU $PROC_S
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Kill -TTOU";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	for ff in 1 2; do
+	    five_sec_sleep
+	done
+	NR=$( egrep "File check completed" $LOGFILE | wc -l )
+	if [ $NR -ne 2 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (2)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "sigttou";
+
+	NR=$( egrep "POLICY" $LOGFILE | wc -l )
+	if [ $NR -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (3)";  
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	# --- The End ---
+
+	kill $PROC_S; 
+	kill $PROC_Y
+	return 0
+}
+
+do_test_2_g_three () {
+
+	#
+	# >>> (1) Modify files, create DeltaDB from file list in ${TEST_LIST}
+	#
+	mod_files
+	#
+	if ! test -f ${TEST_LIST}; then
+	    [ -z "$verbose" ] || log_msg_fail "No file list created";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	#
+	./samhain.new --outfile ./file.delta --create-database "${TEST_LIST}"
+	#
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Create DeltaDB";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	if ! test -f ./file.delta; then
+	    [ -z "$verbose" ] || log_msg_fail "No DeltaDB created";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "... DeltaDB created ...";
+	
+	#
+	# >>> (2) Copy to server and tag with a UUID
+	#
+	UUID=$(uuidgen)
+	if [ x"$1" != "xnosig" ]; then
+	    scripts/samhainadmin.pl -s ./test/gnupg/ -k 8A0B337A -m E ./file.delta >/dev/null
+	fi
+	if [ x"$1" == "xnodelta" ]; then
+	    rm -f ./file.*
+	else
+	    mv ./file.delta file.${SH_LOCALHOST}.${UUID}
+	    cp file.${SH_LOCALHOST}.${UUID} "./file.${ALTHOST}.${UUID}"
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "... DeltaDB copied as file.${SH_LOCALHOST}.${UUID} ...";
+	
+	#
+	# >>> (3) Tell client to load delta database.
+	# >>>     testrc_2: timestamps every 10 sec
+	#
+	grep '^SetLoopTime=10$' rc.${SH_LOCALHOST} >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "SetLoopTime != 10 in rc.${SH_LOCALHOST}";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	grep '^SetLoopTime=10$' rc.${ALTHOST} >/dev/null 2>&1
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "SetLoopTime != 10 in rc.${ALTHOST}";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	./yulectl -c "DELTA:${UUID}" ${SH_LOCALHOST}
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "yulectl (1)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	./yulectl -c "DELTA:${UUID}" ${ALTHOST}
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "yulectl (2)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	NR=$( ./yulectl -c LIST | grep ${UUID} | grep -v grep | wc -l )
+	if [ $NR -ne 2 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "yulectl (3)";
+	    [ -z "$verbose" ] || ./yulectl -c LIST
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "... command sent to client ...";
+
+	# Wait and verify that command has been sent
+	#
+	for tt in 1 2 3 4; do
+	    five_sec_sleep
+	done
+	#
+	NR=$( ./yulectl -c LIST | grep ${UUID} | grep -v grep | wc -l )
+	if [ $NR -ne 1 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "yulectl (4)";
+	    [ -z "$verbose" ] || ./yulectl -c LISTALL
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || OLINE=$( ./yulectl -c LIST | grep ${UUID} )
+	[ -z "$verbose" ] || echo "${OLINE}"
+
+	#
+	# >>> (4) Trigger a scan
+	#
+	kill -TTOU $PROC_S
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Kill -TTOU";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || echo    " ... TTOU sent to /${PROC_S}/ ...";
+	
+	for ff in 1 2; do
+	    five_sec_sleep
+	done
+	if [ x"$1" != x ]; then
+	    if [ x"$1" = xnodelta ]; then
+		NR=$( egrep "File download failed" $LOGFILE | wc -l )
+	    else
+		NR=$( egrep "No good signature" $LOGFILE | wc -l )
+	    fi
+	    if [ $NR -ne 1 ]; then
+		[ -z "$verbose" ] || log_msg_fail "Client file check (expected fail)";
+		kill $PROC_S; kill $PROC_Y;
+		return 1
+	    else
+		[ -z "$verbose" ] || log_msg_ok "Client file check (expected fail)";
+		kill $PROC_S; kill $PROC_Y;
+		return 0
+	    fi
+	fi
+
+	NR=$( egrep "File check completed" $LOGFILE | wc -l )
+	if [ $NR -ne 2 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (2)";
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+	[ -z "$verbose" ] || log_msg_ok    "sigttou";
+
+	NR=$( egrep "POLICY" $LOGFILE | wc -l )
+	if [ $NR -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "Client file check (3)";  
+	    kill $PROC_S; kill $PROC_Y;
+	    return 1
+	fi
+
+	# --- The End ---
+
+	kill $PROC_S; 
+	kill $PROC_Y
+	return 0
+}
+
+testrun2g_prepare ()
+{
+	#####################################################################
+	#
+	# Create test area and initialize database
+	#
+	rm -f ./.samhain_file
+	rm -f ./.samhain_log
+	rm -f ./.samhain_lock
+	rm -f ./rc.${SH_LOCALHOST}
+	rm -f ./rc.${ALTHOST}
+	rm -f ./file.*
+	#
+	rm -rf ${BASE}
+	#
+	mkdir ${BASE} 2>/dev/null
+	for dd in ${TEST_DIRS}; do
+	    mkdir ${BASE}/$dd
+	    for ff in ${TEST_FILES}; do
+		echo "foobar" > ${BASE}/$dd/$ff
+	    done
+	done
+	#
+	./samhain.build -t init -p none
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "init...";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "init...";
+	    return 1
+	fi
+}
+
+testrun2g_build ()
+{
+        [ -z "$verbose" ] || { 
+	    echo; 
+	    echo Working directory: $PW_DIR; echo MAKE is $MAKE; 
+	    echo; 
+	}
+	#
+	#
+	[ -z "$verbose" ] || { echo; echo "${S}Building client and server${E}"; echo; }
+	#
+	if test -r "Makefile"; then
+		$MAKE distclean
+	fi
+	#
+	${TOP_SRCDIR}/configure ${CLIENT_BUILDOPTS} $1 $2 >/dev/null 2>&1
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE > /dev/null 2>>test_log
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	# save binary and build server
+	#
+	cp samhain samhain.build || return 1
+	$MAKE clean >/dev/null || return 1
+
+	${TOP_SRCDIR}/configure ${SERVER_BUILDOPTS}
+	#
+	if test x$? = x0; then
+		[ -z "$verbose" ] ||     log_msg_ok "configure..."; 
+		$MAKE  > /dev/null 2>>test_log
+		if test x$? = x0; then
+		    [ -z "$verbose" ] || log_msg_ok "make..."; 
+		else
+		    [ -z "$quiet" ] &&   log_msg_fail "make..."; 
+		    return 1
+		fi
+
+	else
+		[ -z "$quiet" ] &&       log_msg_fail "configure...";
+		return 1
+	fi
+
+	# Create a password
+
+	SHPW=`./yule -G`
+	if test x"$SHPW" = x; then
+	    [ -z "$quiet" ]   && log_msg_fail  "password not generated -- aborting"
+	    return 1
+	fi
+
+	# Set in client
+
+	./samhain_setpwd samhain.build new $SHPW >/dev/null
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "./samhain_setpwd samhain.build new $SHPW";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "./samhain_setpwd samhain.build new $SHPW";
+	    return 1
+	fi
+
+	mv samhain.build.new  samhain.new || return 1
+
+	rm -f ./.samhain_log*
+	rm -f ./.samhain_lock
+
+	SHCLT=`./yule -P $SHPW`
+
+	if test x$? = x0; then
+	    [ -z "$verbose" ] || log_msg_ok    "yule -P $SHPW";
+	else
+	    [ -z "$quiet" ]   && log_msg_fail  "yule -P $SHPW";
+	    return 1
+	fi
+
+	SHCLT1=`echo "${SHCLT}"  | sed s%HOSTNAME%${SH_LOCALHOST}%`
+	AHOST=`find_hostname`
+	SHCLT2=`echo "${SHCLT}"  | sed s%HOSTNAME%${AHOST}%`
+	
+	cp ${SCRIPTDIR}/testrc_2.in testrc_2
+	#
+	sed --in-place -e 's,file = /tmp,dir = 99/tmp/testrun_samhain,g' testrc_2
+	# 
+	sed --in-place -e 's,SetUdpActive=no,ReportCheckflags=yes,g' testrc_2
+	#
+ 	echo $SHCLT1 >> testrc_2
+ 	echo $SHCLT2 >> testrc_2
+
+	echo $SHPW > ./testpw
+}
+
+testrun2g_signrc ()
+{
+    scripts/samhainadmin.pl -s ./test/gnupg/ -m R $1 >/dev/null
+    scripts/samhainadmin.pl -s ./test/gnupg/ -k 8A0B337A -m E $1 >/dev/null
+}
+
+testrun2g_signdb ()
+{
+    scripts/samhainadmin.pl -s ./test/gnupg/ -k 8A0B337A -m E ./.samhain_file >/dev/null
+}
+
+copy_rc_db_files ()
+{
+	cp    ./testrc_2       ./rc.${SH_LOCALHOST}
+	mv    ./.samhain_file  ./file.${SH_LOCALHOST}
+	if [ $? -ne 0 ]; then
+	    [ -z "$verbose" ] || log_msg_fail "No .samhain_file";
+	    return 1
+	fi
+	chmod 644 ./rc.${SH_LOCALHOST}
+	chmod 644 ./file.${SH_LOCALHOST}
+
+	cp    ./testrc_2       "./rc.${ALTHOST}"
+	cp    ./file.${SH_LOCALHOST} "./file.${ALTHOST}" 2>/dev/null
+	chmod 644 ./rc.${ALTHOST}
+	chmod 644 ./file.${ALTHOST}
+}
+
+MAXTEST=6; export MAXTEST
+
+testrun2g ()
+{
+    log_start "RUN CLIENT/SERVER CASE TWO";
+    #
+    if [ x"$1" = x ]; then
+	[ -z "$quiet" ] && log_msg_fail "Missing hostname"
+    fi
+    #
+    SH_LOCALHOST=$1; export SH_LOCALHOST
+    #
+
+
+    # Test with missing delta
+    #
+    gpg --list-keys | grep 8A0B337A >/dev/null 2>&1
+    if [ $? -ne 0 ]; then
+	echo "You need to do 'gpg --import test/gnupg/public-key.asc' first"
+	log_skip 1 $MAXTEST 'Case Two w/signed files'
+    else
+	testrun2g_build "--with-gpg=/usr/bin/gpg" "--with-keyid=0x8A0B337A"
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "build..";
+	    testrun2g_signrc ./testrc_2
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "sign rc..";
+	    testrun2g_prepare
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "prepare..";
+	    testrun2g_signdb
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "sign db..";
+	    copy_rc_db_files
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "copy..";
+	    do_test_2_g_yule_start
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "start yule..";
+	    do_test_2_g_three nodelta
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$quiet" ] && log_ok   1 ${MAXTEST} "Case Two w/missing delta";
+	else
+	    [ -z "$quiet" ] && log_fail 1 ${MAXTEST} "Case Two w/missing delta";
+	fi
+    fi
+
+    # Test with unsigned delta
+    #
+    gpg --list-keys | grep 8A0B337A >/dev/null 2>&1
+    if [ $? -ne 0 ]; then
+	echo "You need to do 'gpg --import test/gnupg/public-key.asc' first"
+	log_skip 1 $MAXTEST 'Case Two w/signed files'
+    else
+	testrun2g_build "--with-gpg=/usr/bin/gpg" "--with-keyid=0x8A0B337A"
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "build..";
+	    testrun2g_signrc ./testrc_2
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "sign rc..";
+	    testrun2g_prepare
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "prepare..";
+	    testrun2g_signdb
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "sign db..";
+	    copy_rc_db_files
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "copy..";
+	    do_test_2_g_yule_start
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "start yule..";
+	    do_test_2_g_three nosig
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$quiet" ] && log_ok   1 ${MAXTEST} "Case Two w/unsigned delta";
+	else
+	    [ -z "$quiet" ] && log_fail 1 ${MAXTEST} "Case Two w/unsigned delta";
+	fi
+    fi
+
+    # Test with signed files, no sig client
+    #
+    gpg --list-keys | grep 8A0B337A >/dev/null 2>&1
+    if [ $? -ne 0 ]; then
+	echo "You need to do 'gpg --import test/gnupg/public-key.asc' first"
+	log_skip 1 $MAXTEST 'Case Two w/signed files'
+    else
+	testrun2g_build
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "build..";
+	    testrun2g_signrc ./testrc_2
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "sign rc..";
+	    testrun2g_prepare
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "prepare..";
+	    testrun2g_signdb
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "sign db..";
+	    copy_rc_db_files
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "copy..";
+	    do_test_2_g_yule_start
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "start yule..";
+	    do_test_2_g_three
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$quiet" ] && log_ok   1 ${MAXTEST} "Case Two w/signed files+nosig client";
+	else
+	    [ -z "$quiet" ] && log_fail 1 ${MAXTEST} "Case Two w/signed files+nosig client";
+	fi
+    fi
+
+    # Test with signed files
+    #
+    gpg --list-keys | grep 8A0B337A >/dev/null 2>&1
+    if [ $? -ne 0 ]; then
+	echo "You need to do 'gpg --import test/gnupg/public-key.asc' first"
+	log_skip 1 $MAXTEST 'Case Two w/signed files'
+    else
+	testrun2g_build "--with-gpg=/usr/bin/gpg" "--with-keyid=0x8A0B337A"
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "build..";
+	    testrun2g_signrc ./testrc_2
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "sign rc..";
+	    testrun2g_prepare
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "prepare..";
+	    testrun2g_signdb
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "sign db..";
+	    copy_rc_db_files
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "copy..";
+	    do_test_2_g_yule_start
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$verbose" ] || log_msg_ok    "start yule..";
+	    do_test_2_g_three
+	fi
+	if [ $? -eq 0 ]; then
+	    [ -z "$quiet" ] && log_ok   1 ${MAXTEST} "Case Two w/signed files";
+	else
+	    [ -z "$quiet" ] && log_fail 1 ${MAXTEST} "Case Two w/signed files";
+	fi
+    fi
+
+    # Test with non-signed files
+    #
+    testrun2g_build
+    if [ $? -eq 0 ]; then
+	[ -z "$verbose" ] || log_msg_ok    "build..";
+	testrun2g_prepare
+    fi
+    if [ $? -eq 0 ]; then
+	[ -z "$verbose" ] || log_msg_ok    "prepare..";
+	copy_rc_db_files
+    fi
+    if [ $? -eq 0 ]; then
+	[ -z "$verbose" ] || log_msg_ok    "copy..";
+	do_test_2_g_yule_start
+    fi
+    if [ $? -eq 0 ]; then
+	[ -z "$verbose" ] || log_msg_ok    "start yule..";
+	do_test_2_g_one
+    fi
+    if [ $? -eq 0 ]; then
+	[ -z "$quiet" ] && log_ok   2 ${MAXTEST} "Case Two w/unsigned files";
+    else
+	[ -z "$quiet" ] && log_fail 2 ${MAXTEST} "Case Two w/unsigned files";
+    fi
+
+
+
+    #
+    testrun2g_prepare
+    if [ $? -eq 0 ]; then
+	[ -z "$verbose" ] || log_msg_ok    "prepare..";
+	copy_rc_db_files
+    fi
+    if [ $? -eq 0 ]; then
+	[ -z "$verbose" ] || log_msg_ok    "copy..";
+	do_test_2_g_yule_start
+    fi
+    if [ $? -eq 0 ]; then
+	[ -z "$verbose" ] || log_msg_ok    "start yule..";
+	do_test_2_g_two
+    fi
+    if [ $? -eq 0 ]; then
+	[ -z "$quiet" ] && log_ok   3 ${MAXTEST} "Case Two w/o delta";
+    else
+	[ -z "$quiet" ] && log_fail 3 ${MAXTEST} "Case Two w/o delta";
+    fi
+
+
+    log_end "RUN CLIENT/SERVER CASE TWO"
+}
