diff -I '\$Id: ' -u -r -b -w -p -d --exclude-from=/home/rstory/.rcfiles/diff-ignore --new-file libspf2-1.2.9/configure.ac libspf2-1.2.9.dnssec/configure.ac
--- libspf2-1.2.9/configure.ac	2008-11-04 10:32:10.000000000 -0500
+++ libspf2-1.2.9.dnssec/configure.ac	2010-06-03 10:20:17.000000000 -0400
@@ -109,6 +109,84 @@ AC_CHECK_HEADER(pthread.h, , [
 	exit 1;
 ])
 
+AC_MSG_CHECKING(whether we need to support DNSSEC validation)
+AC_ARG_ENABLE(dnssec-support,
+[  --enable-dnssec-support Support DNSSEC validation.],
+    support_dnssec=yes)
+
+if test "x$support_dnssec" = "xyes"; then
+
+   AC_MSG_RESULT(yes)
+
+   dnl Check DNSSEC Validator library header
+   AC_CHECK_HEADERS([validator/validator.h])
+
+   dnl Check the openssl crypto library
+   AC_ARG_WITH(openssl,
+    [  --with-openssl=PATH     Look for openssl in PATH/{lib,include}.],
+    if test "x$withval" != "xyes"; then
+      if test "x$withval" != x -a -d $withval/lib; then
+          LDFLAGS="-L$withval/lib $LDFLAGS"
+      fi
+      if test "x$withval" != x -a -d $withval/include; then
+          CPPFLAGS="-I$withval/include $CPPFLAGS"
+      fi
+    fi
+   )
+   AC_CHECK_LIB(crypto, RSA_verify, , [
+	echo "the openssl crypto library is required to build this program."
+	exit 1;
+   ])
+
+   dnl Check libsres
+   AC_ARG_WITH(libsres,
+	[  --with-libsres=PATH     Look for the libsres library in PATH],
+	if test "x$withval" != "xyes"; then
+	  if test "x$withval" != x -a -d $withval/lib; then
+	      LDFLAGS="-L$withval/lib $LDFLAGS"
+	      AC_MSG_CHECKING(libsres)
+	      AC_MSG_RESULT("$withval")
+	  fi
+      if test "x$withval" != x -a -d $withval/include; then
+          CPPFLAGS="-I$withval/include $CPPFLAGS"
+      fi
+	fi
+   )
+
+   dnl Check Secure Resolver Library libsres
+   AC_CHECK_LIB(sres, query_send, , [
+	echo "the secure resolver library is required to build this program."
+	echo "see http://dnssec-tools.sourceforge.net"
+	exit 1;
+   ], -L/usr/local/lib)
+
+   dnl Check libval
+   AC_ARG_WITH(libval-threads,
+	[  --with-libval=PATH      Look for the libval library in PATH],
+	if test "x$withval" != "xyes"; then
+	  if test "x$withval" != x -a -d $withval/lib; then
+	      LDFLAGS="-L$withval/lib $LDFLAGS"
+	      AC_MSG_CHECKING(libval)
+	      AC_MSG_RESULT("$withval")
+	  fi
+      if test "x$withval" != x -a -d $withval/include; then
+          CPPFLAGS="-I$withval/include $CPPFLAGS"
+      fi
+	fi
+   )
+
+   dnl Check DNSSEC Validator library
+   AC_CHECK_LIB(val-threads, val_resolve_and_check, , [
+	echo "the validator library is required to build this program."
+        echo "see http://dnssec-tools.sourceforge.net"
+	exit 1;
+   ], -lsres -lcrypto -lpthread -L/usr/local/lib)
+
+   AC_DEFINE([SUPPORT_DNSSEC], [], [Support DNSSEC validation])
+
+else
+   AC_MSG_RESULT(no)
+
 dnl Moved to after header checks by Shevek
 AC_ARG_WITH(bind,
         [  --with-bind=DIR  Find BIND resolver in DIR],
@@ -138,6 +216,7 @@ AC_ARG_WITH(bind,
 								LIBS="$saved_libs"])
         ])
 		
+fi		
 		
 		
 dnl [AC_CHECK_LIB(resolv, res_query)])
diff -I '\$Id: ' -u -r -b -w -p -d --exclude-from=/home/rstory/.rcfiles/diff-ignore --new-file libspf2-1.2.9/src/include/spf_dns.h libspf2-1.2.9.dnssec/src/include/spf_dns.h
--- libspf2-1.2.9/src/include/spf_dns.h	2008-10-27 12:27:14.000000000 -0400
+++ libspf2-1.2.9.dnssec/src/include/spf_dns.h	2009-12-16 14:36:04.794058930 -0500
@@ -105,6 +105,15 @@ typedef int	ns_type;
 #define	NO_RECOVERY		3		/**< invalid/unimplmeneted query	*/
 #define	NO_DATA			4		/**< host found, but no RR of req type*/
 #endif
+
+#ifdef SUPPORT_DNSSEC
+/*
+ * Additional Error code for DNSSEC validation
+ */
+#define DNSSEC_FAILURE  5               /* DNSSEC validation failed. */
+#include <netinet/in.h>
+#endif
+
 typedef int SPF_dns_stat_t;
 
 typedef struct SPF_dns_server_struct SPF_dns_server_t;
diff -I '\$Id: ' -u -r -b -w -p -d --exclude-from=/home/rstory/.rcfiles/diff-ignore --new-file libspf2-1.2.9/src/include/spf_response.h libspf2-1.2.9.dnssec/src/include/spf_response.h
--- libspf2-1.2.9/src/include/spf_response.h	2008-10-15 20:08:12.000000000 -0400
+++ libspf2-1.2.9.dnssec/src/include/spf_response.h	2009-12-16 14:37:00.585318575 -0500
@@ -151,6 +151,10 @@ enum SPF_errcode_t {
 ,	SPF_E_INCLUDE_RETURNED_NONE	/**< If an include recursive query returns none it's a perm error */
 ,	SPF_E_RECURSIVE			/**< Recursive include */
 ,	SPF_E_MULTIPLE_RECORDS	/**< Multiple SPF or TXT records found */
+
+#ifdef SUPPORT_DNSSEC
+,	SPF_E_DNSSEC_FAILURE		/* DNSSEC validation failure */
+#endif
 } SPF_errcode_t;
 
 typedef
diff -I '\$Id: ' -u -r -b -w -p -d --exclude-from=/home/rstory/.rcfiles/diff-ignore --new-file libspf2-1.2.9/src/libspf2/spf_dns_resolv.c libspf2-1.2.9.dnssec/src/libspf2/spf_dns_resolv.c
--- libspf2-1.2.9/src/libspf2/spf_dns_resolv.c	2008-10-27 12:26:06.000000000 -0400
+++ libspf2-1.2.9.dnssec/src/libspf2/spf_dns_resolv.c	2010-06-03 11:18:10.000000000 -0400
@@ -58,6 +58,11 @@
 # include <pthread.h>
 #endif
 
+#ifdef SUPPORT_DNSSEC
+#undef HAVE_DECL_RES_NINIT
+#include <validator/validator.h>
+#endif /* SUPPORT_DNSSEC */
+
 #include "spf.h"
 #include "spf_dns.h"
 #include "spf_internal.h"
@@ -79,13 +84,17 @@ static const struct res_sym ns_sects[] =
 static const int num_ns_sect = sizeof(ns_sects) / sizeof(*ns_sects);
 
 
+#ifdef SUPPORT_DNSSEC
+# define SPF_h_errno h_errno
+#else
 #if HAVE_DECL_RES_NINIT
 # define SPF_h_errno res_state->res_h_errno
 #else
 # define SPF_h_errno h_errno
 #endif
+#endif
 
-#if HAVE_DECL_RES_NINIT
+#if HAVE_DECL_RES_NINIT && ! defined(SUPPORT_DNSSEC)
 static pthread_once_t	res_state_control = PTHREAD_ONCE_INIT;
 static pthread_key_t	res_state_key;
 
@@ -239,14 +248,16 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *
 	size_t	rdlen;
 	const u_char	*rdata;
 
-#if HAVE_DECL_RES_NINIT
+#if defined(SUPPORT_DNSSEC)
+	val_status_t dnssec_status = VAL_INTERNAL_ERROR;
+#elif HAVE_DECL_RES_NINIT
 	void				*res_spec;
 	struct __res_state	*res_state;
 #endif
 
 	SPF_ASSERT_NOTNULL(spf_dns_server);
 
-#if HAVE_DECL_RES_NINIT
+#if HAVE_DECL_RES_NINIT && ! defined(SUPPORT_DNSSEC)
 	/** Get the thread-local resolver state. */
 	res_spec = pthread_getspecific(res_state_key);
 	if (res_spec == NULL) {
@@ -292,7 +303,14 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *
 	for (;;) {
 		int	dns_len;
 
-#if HAVE_DECL_RES_NINIT
+#ifdef SUPPORT_DNSSEC
+	dns_len = val_res_query( NULL, domain, ns_c_in, rr_type, 
+                            responsebuf, responselen, &dnssec_status );
+	if (dns_len >= 0) {
+		SPF_debugf( "val_res_query() returned dnssec_status = %s\n", 
+				    p_val_status( dnssec_status ) );
+	}
+#elif HAVE_DECL_RES_NINIT
 		/* Resolve the name. */
 		dns_len = res_nquery(res_state, domain, ns_c_in, rr_type,
 				 responsebuf, responselen);
@@ -314,6 +332,16 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *
 				return SPF_dns_lookup(spf_dns_server->layer_below,
 								domain, rr_type, should_cache);
 			}
+#ifdef SUPPORT_DNSSEC
+			if ( !val_istrusted(dnssec_status) ) {
+				if ( h_errno == NETDB_SUCCESS ) {
+					h_errno = DNSSEC_FAILURE;
+				}
+				return SPF_dns_rr_new_init( spf_dns_server,
+							    domain, rr_type, 0, h_errno );
+			}
+			else
+#endif
 			return SPF_dns_rr_new_init(spf_dns_server,
 							domain, rr_type, 0, SPF_h_errno);
 		}
@@ -348,6 +376,16 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *
 	/*
 	 * initialize stuff
 	 */
+#ifdef SUPPORT_DNSSEC
+	if ( !val_istrusted(dnssec_status) ) {
+		if ( h_errno == NETDB_SUCCESS ) {
+			h_errno = DNSSEC_FAILURE;
+		}
+		spfrr = SPF_dns_rr_new_init( spf_dns_server,
+					     domain, rr_type, 0, h_errno );
+	}
+	else
+#endif
 	spfrr = SPF_dns_rr_new_init(spf_dns_server,
 					domain, rr_type, 0, NETDB_SUCCESS);
 	if (!spfrr) {
@@ -369,6 +407,7 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *
 	}
 
 
+#ifndef SUPPORT_DNSSEC
 	if (spf_dns_server->debug > 1) {
 		SPF_debugf("msg id:             %d", ns_msg_id(ns_handle));
 		SPF_debugf("ns_f_qr quest/resp: %d", ns_msg_getflag(ns_handle, ns_f_qr));
@@ -379,6 +418,7 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *
 		SPF_debugf("ns_f_ra rec avail:  %d", ns_msg_getflag(ns_handle, ns_f_ra));
 		SPF_debugf("ns_f_rcode:         %d", ns_msg_getflag(ns_handle, ns_f_rcode));
 	}
+#endif
 
 
 	/* FIXME  the error handling from here on is suspect at best */
@@ -596,6 +636,14 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *
 	if (spfrr->num_rr == 0)
 		spfrr->herrno = NO_DATA;
 
+#ifdef SUPPORT_DNSSEC
+	if ( !val_istrusted(dnssec_status) ) {
+		if ( spfrr->herrno == NETDB_SUCCESS ) {
+			spfrr->herrno = DNSSEC_FAILURE;
+		}
+	}
+#endif
+
 	free(responsebuf);
 	return spfrr;
 }
@@ -606,7 +654,7 @@ SPF_dns_resolv_free(SPF_dns_server_t *sp
 {
 	SPF_ASSERT_NOTNULL(spf_dns_server);
 
-#if ! HAVE_DECL_RES_NINIT
+#if ! HAVE_DECL_RES_NINIT && !defined(SUPPORT_DNSSEC)
 	res_close();
 #endif
 
@@ -619,7 +667,9 @@ SPF_dns_resolv_new(SPF_dns_server_t *lay
 {
 	SPF_dns_server_t		*spf_dns_server;
 
-#if HAVE_DECL_RES_NINIT
+#if defined(SUPPORT_DNSSEC)
+	;
+#elif HAVE_DECL_RES_NINIT
 	pthread_once(&res_state_control, SPF_dns_resolv_init_key);
 #else
 	if (res_init() != 0) {
diff -I '\$Id: ' -u -r -b -w -p -d --exclude-from=/home/rstory/.rcfiles/diff-ignore --new-file libspf2-1.2.9/src/libspf2/spf_get_exp.c libspf2-1.2.9.dnssec/src/libspf2/spf_get_exp.c
--- libspf2-1.2.9/src/libspf2/spf_get_exp.c	2008-10-02 18:07:42.000000000 -0400
+++ libspf2-1.2.9.dnssec/src/libspf2/spf_get_exp.c	2009-12-17 13:05:30.631935143 -0500
@@ -173,6 +173,13 @@ SPF_request_get_exp(SPF_server_t *spf_se
 			RETURN_DEFAULT_EXP();
 			break;
 
+#ifdef SUPPORT_DNSSEC
+		case DNSSEC_FAILURE:
+		        SPF_response_add_warn(spf_response, SPF_E_DNSSEC_FAILURE,
+					      "DNSSEC validation failed for the SPF (TXT) record of '%s'.",
+					      *bufp);
+			break;
+#endif
 		case NETDB_SUCCESS:
 			break;
 
diff -I '\$Id: ' -u -r -b -w -p -d --exclude-from=/home/rstory/.rcfiles/diff-ignore --new-file libspf2-1.2.9/src/libspf2/spf_interpret.c libspf2-1.2.9.dnssec/src/libspf2/spf_interpret.c
--- libspf2-1.2.9/src/libspf2/spf_interpret.c	2008-10-22 11:47:43.000000000 -0400
+++ libspf2-1.2.9.dnssec/src/libspf2/spf_interpret.c	2009-12-18 10:19:04.607247133 -0500
@@ -284,6 +284,14 @@ SPF_i_set_received_spf(SPF_response_t *s
 	
 	char			*p, *p_end;
 
+#ifdef SUPPORT_DNSSEC
+	int 		 firstdnssecerr;
+	int 		 i;
+	int 		 num_errs;
+	SPF_error_t 	*err;
+	SPF_errcode_t 	 errcode;
+	const char 	*errmsg = "";
+#endif
 	SPF_ASSERT_NOTNULL(spf_response);
 	spf_request = spf_response->spf_request;
 	SPF_ASSERT_NOTNULL(spf_request);
@@ -358,6 +366,57 @@ SPF_i_set_received_spf(SPF_response_t *s
 		}
 #endif
 
+#ifdef SUPPORT_DNSSEC
+		/* add in the DNSSEC validation status */
+		firstdnssecerr = 1;
+		num_errs = SPF_response_warnings( spf_response );
+		for ( i = 0; i < num_errs; i++ )
+		{
+		    err = SPF_response_message( spf_response, i );
+		    if ( err )
+		    {
+			errcode = SPF_error_code ( err );
+			if ( errcode == SPF_E_DNSSEC_FAILURE )
+			{
+			    errmsg = SPF_error_message( err );
+			    if ( errmsg == NULL ) errmsg = "";
+
+			    if ( firstdnssecerr )
+			    {
+				p += snprintf( p, p_end - p,
+					       " x-dnssec=\"fail (%s",
+					       errmsg );
+				firstdnssecerr = 0;
+			    }
+			    else
+			    {
+				p += snprintf( p, p_end - p, ", %s", errmsg );
+			    }
+			}
+			if ( p_end - p <= 0 ) break;
+		    }
+		}
+
+		if ( p_end - p <= 0 ) break;
+
+		if ( firstdnssecerr )
+		{
+		    if ( spf_response->result != SPF_RESULT_NONE )
+		    {
+			p += snprintf( p, p_end - p, " x-dnssec=\"pass\";" );
+		    }
+		    else
+		    {
+			p += snprintf( p, p_end - p, " x-dnssec=\"none\";" );
+		    }
+		}
+		else
+		{
+		    p += snprintf( p, p_end - p, ")\";" );
+		}
+
+		if ( p_end - p <= 0 ) break;
+#endif
 		/* FIXME  should the explanation string be included in the header? */
 
 		/* FIXME  should the header be reformated to include line breaks? */
@@ -787,6 +846,15 @@ SPF_record_interpret(SPF_record_t *spf_r
 				return DONE_TEMPERR(SPF_E_DNS_ERROR); /* REASON_MECH */
 			}
 
+#ifdef SUPPORT_DNSSEC
+			if ( rr_a->herrno == DNSSEC_FAILURE )
+			{
+			        SPF_response_add_warn( spf_response,
+						       SPF_E_DNSSEC_FAILURE,
+						       "DNSSEC validation failed for the A record of '%s'.",
+						       lookup );	    
+			}
+#endif
 			for (i = 0; i < rr_a->num_rr; i++) {
 				/* XXX Should this be hoisted? */
 				if (rr_a->rr_type != fetch_ns_type)
@@ -828,6 +896,15 @@ SPF_record_interpret(SPF_record_t *spf_r
 				return DONE_TEMPERR(SPF_E_DNS_ERROR);
 			}
 
+#ifdef SUPPORT_DNSSEC
+			if ( rr_mx->herrno == DNSSEC_FAILURE ) {
+			        SPF_response_add_warn( spf_response,
+						       SPF_E_DNSSEC_FAILURE,
+						       "DNSSEC validation failed for the MX record of '%s'.",
+						       lookup );	    
+			}
+#endif
+
 			/* The maximum number of MX records we will inspect. */
 			max_mx = rr_mx->num_rr;
 			max_exceeded = 0;
@@ -859,6 +936,21 @@ SPF_record_interpret(SPF_record_t *spf_r
 					return DONE_TEMPERR(SPF_E_DNS_ERROR);
 				}
 
+#ifdef SUPPORT_DNSSEC
+				if ( rr_a->herrno == DNSSEC_FAILURE ) {
+					if ( spf_request->client_ver == AF_INET ) {
+						SPF_response_add_warn( spf_response, SPF_E_DNSSEC_FAILURE,
+								       "DNSSEC validation failed for the A record of '%s'.",
+								       rr_mx->rr[j]->mx );
+					}
+					else {
+						SPF_response_add_warn( spf_response, SPF_E_DNSSEC_FAILURE,
+								       "DNSSEC validation failed for the AAAA record of '%s'.",
+								       rr_mx->rr[j]->mx );
+					}
+				}
+#endif
+
 				for (i = 0; i < rr_a->num_rr; i++) {
 					/* XXX Should this be hoisted? */
 					if (rr_a->rr_type != fetch_ns_type)
@@ -941,6 +1033,14 @@ SPF_record_interpret(SPF_record_t *spf_r
 						return DONE_TEMPERR( SPF_E_DNS_ERROR );
 					}
 
+#ifdef SUPPORT_DNSSEC
+					if( rr_a->herrno == DNSSEC_FAILURE ) {
+					        SPF_response_add_warn( spf_response, SPF_E_DNSSEC_FAILURE,
+								       "DNSSEC validation failed for the A record of '%s'.",
+								       rr_ptr->rr[i]->ptr );
+					}
+#endif
+
 					for (j = 0; j < rr_a->num_rr; j++) {
 						/* XXX MX has a 'continue' case here which should be hoisted. */
 
@@ -1012,6 +1112,14 @@ SPF_record_interpret(SPF_record_t *spf_r
 						return DONE_TEMPERR( SPF_E_DNS_ERROR );
 					}
 
+#ifdef SUPPORT_DNSSEC
+					if( rr_aaaa->herrno == DNSSEC_FAILURE ) {
+					        SPF_response_add_warn( spf_response, SPF_E_DNSSEC_FAILURE,
+								       "DNSSEC validation failed for the AAAA record of '%s'.",
+								       rr_ptr->rr[i]->ptr );
+					}
+#endif
+
 					for( j = 0; j < rr_aaaa->num_rr; j++ ) {
 						/* XXX MX has a 'continue' case here which should be hoisted. */
 						if ( spf_server->debug ) {
@@ -1150,6 +1258,32 @@ SPF_record_interpret(SPF_record_t *spf_r
 				spf_response = save_spf_response;
 				save_spf_response = NULL;
 
+#ifdef SUPPORT_DNSSEC
+				/* Copy any DNSSEC validation warnings from
+				 * spf_response_subr to spf_response
+				 */
+				do {
+				    int num_errs;
+				    int i;
+				    SPF_error_t *err;
+				    SPF_errcode_t errcode;
+				    char *errmsg;
+
+				    num_errs = SPF_response_warnings( spf_response_subr );
+				    for ( i = 0; i < num_errs; i++ ) {
+					err = SPF_response_message( spf_response_subr, i );
+					if ( err ) {
+					    errcode = SPF_error_code( err );
+					    if ( errcode == SPF_E_DNSSEC_FAILURE ) {
+						errmsg = ( char * ) SPF_error_message( err );
+					        SPF_response_add_warn( spf_response,
+								       SPF_E_DNSSEC_FAILURE,
+								       errmsg );
+					    }
+					}
+				    }
+				} while (0);
+#endif
 				/* Rewrite according to prefix of include */
 				switch (SPF_response_result(spf_response_subr)) {
 					case SPF_RESULT_PASS:
@@ -1234,6 +1368,15 @@ SPF_record_interpret(SPF_record_t *spf_r
 				SPF_FREE_LOOKUP_DATA();
 				return DONE_TEMPERR(SPF_E_DNS_ERROR);
 			}
+
+#ifdef SUPPORT_DNSSEC
+			if( rr_a->herrno == DNSSEC_FAILURE ) {
+			        SPF_response_add_warn( spf_response, SPF_E_DNSSEC_FAILURE,
+						       "DNSSEC validation failed for the A record of '%s'.",
+						       lookup );
+			}
+#endif
+
 			if ( rr_a->num_rr > 0 ) {
 				SPF_dns_rr_free(rr_a);
 				SPF_FREE_LOOKUP_DATA();
diff -I '\$Id: ' -u -r -b -w -p -d --exclude-from=/home/rstory/.rcfiles/diff-ignore --new-file libspf2-1.2.9/src/libspf2/spf_server.c libspf2-1.2.9.dnssec/src/libspf2/spf_server.c
--- libspf2-1.2.9/src/libspf2/spf_server.c	2008-11-03 19:09:49.000000000 -0500
+++ libspf2-1.2.9.dnssec/src/libspf2/spf_server.c	2009-12-30 14:44:18.995746790 -0500
@@ -400,6 +400,13 @@ retry:
 				SPF_debugf("get_record(%s): NETDB_SUCCESS", domain);
 			break;
 
+#ifdef SUPPORT_DNSSEC
+		case DNSSEC_FAILURE:
+			SPF_response_add_warn(spf_response, SPF_E_DNSSEC_FAILURE,
+					      "DNSSEC validation failed for the SPF (TXT) record of '%s'.",
+					      domain);
+			break;
+#endif
 		default:
 			if (spf_server->debug > 0)
 				SPF_debugf("get_record(%s): UNKNOWN_ERROR", domain);
diff -I '\$Id: ' -u -r -b -w -p -d --exclude-from=/home/rstory/.rcfiles/diff-ignore --new-file libspf2-1.2.9/src/libspf2/spf_strerror.c libspf2-1.2.9.dnssec/src/libspf2/spf_strerror.c
--- libspf2-1.2.9/src/libspf2/spf_strerror.c	2008-10-06 19:54:08.000000000 -0400
+++ libspf2-1.2.9.dnssec/src/libspf2/spf_strerror.c	2009-12-30 14:45:16.005861646 -0500
@@ -166,6 +166,12 @@ SPF_strerror( SPF_errcode_t spf_c_err )
 	return "Multiple SPF or TXT records for domain.";
 	break;
 
+#ifdef SUPPORT_DNSSEC
+    case SPF_E_DNSSEC_FAILURE:
+	return "DNSSEC Validation of SPF record failed";
+	break;
+#endif
+
     default:
 	return "Unknown SPF error code";
 	break;
