Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > ccd6d20295ff28f0d90115b0394355f1 > files > 26

libdnssec-tools-devel-1.5-2mdv2010.0.i586.rpm

diff -U 5 -r libspf2-1.2.5.orig/config.h.in libspf2-1.2.5/config.h.in
--- libspf2-1.2.5.orig/config.h.in	2005-02-23 21:15:21.000000000 -0500
+++ libspf2-1.2.5/config.h.in	2008-04-25 14:14:38.000000000 -0400
@@ -44,10 +44,13 @@
 #undef HAVE_INET_NTOA
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
+
 /* Define to 1 if you have the `intl' library (-lintl). */
 #undef HAVE_LIBINTL
 
 /* Define to 1 if you have the <libintl.h> header file. */
 #undef HAVE_LIBINTL_H
@@ -59,10 +62,16 @@
 #undef HAVE_LIBPTHREAD
 
 /* Define to 1 if you have the `socket' library (-lsocket). */
 #undef HAVE_LIBSOCKET
 
+/* Define to 1 if you have the `sres' library (-lsres). */
+#undef HAVE_LIBSRES
+
+/* Define to 1 if you have the `val-threads' library (-lval-threads). */
+#undef HAVE_LIBVAL_THREADS
+
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
 /* Define to 1 if your system has a GNU libc compatible `malloc' function, and
    to 0 otherwise. */
@@ -211,10 +220,13 @@
 #undef HAVE_U_INT32_T
 
 /* Define to 1 if the system has the type `u_int8_t'. */
 #undef HAVE_U_INT8_T
 
+/* Define to 1 if you have the <validator/validator.h> header file. */
+#undef HAVE_VALIDATOR_VALIDATOR_H
+
 /* Define to 1 if you have the `vfork' function. */
 #undef HAVE_VFORK
 
 /* Define to 1 if you have the <vfork.h> header file. */
 #undef HAVE_VFORK_H
@@ -274,10 +286,13 @@
 #undef SIZEOF_INT
 
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
+/* Support DNSSEC validation */
+#undef SUPPORT_DNSSEC
+
 /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
 #undef TIME_WITH_SYS_TIME
 
 /* Version number of package */
 #undef VERSION
diff -U 5 -r libspf2-1.2.5.orig/configure.ac libspf2-1.2.5/configure.ac
--- libspf2-1.2.5.orig/configure.ac	2005-02-23 21:09:34.000000000 -0500
+++ libspf2-1.2.5/configure.ac	2008-04-25 14:14:38.000000000 -0400
@@ -90,39 +90,112 @@
 AC_CHECK_HEADER(pthread.h, , [
 	echo "pthread.h is required to build this program."
 	exit 1;
 ])
 
-dnl Moved to after header checks by Shevek
-AC_ARG_WITH(bind,
-        [  --with-bind=DIR  Find BIND resolver in DIR],
-        [AC_CHECK_FILE([$withval/include/bind/resolv.h],
-                [CFLAGS="$CFLAGS -I$withval/include/bind"],
-                [CFLAGS="$CFLAGS -I$withval/include"])
-         LDFLAGS="$LDFLAGS -L$withval/lib -Wl,$rpath$withval/lib"
-         AC_CHECK_LIB([bind], [res_query], [LIBS="$LIBS -lbind"],
-                [AC_CHECK_LIB([resolv],
-                        [res_query],
-                        [LIBS="$LIBS -lresolv"],
-                        [echo "cannot find resolver library"; exit 1;])
-                ])
-        ],
-		[dnl Have to include resolv.h as res_query is sometimes defined as a macro
-				AC_MSG_CHECKING([for res_query in -lresolv (with resolv.h if present)])
-				saved_libs="$LIBS"
-				LIBS="-lresolv $LIBS"
-				AC_TRY_LINK([
-						#ifdef HAVE_RESOLV_H
-						#include <resolv.h>
-						#endif],
-						[res_query(0,0,0,0,0)],
-						[AC_MSG_RESULT(yes)
-								have_res_query=yes],
-						[AC_MSG_RESULT(no)
-								LIBS="$saved_libs"])
-        ])
-		
+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; then
+	      LDFLAGS="-L$withval $LDFLAGS"
+	      AC_MSG_CHECKING(libsres)
+	      AC_MSG_RESULT("$withval")
+	  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; then
+	      LDFLAGS="-L$withval $LDFLAGS"
+	      AC_MSG_CHECKING(libval)
+	      AC_MSG_RESULT("$withval")
+	  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],
+         [AC_CHECK_FILE([$withval/include/bind/resolv.h],
+                 [CFLAGS="$CFLAGS -I$withval/include/bind"],
+                 [CFLAGS="$CFLAGS -I$withval/include"])
+          LDFLAGS="$LDFLAGS -L$withval/lib -Wl,$rpath$withval/lib"
+          AC_CHECK_LIB([bind], [res_query], [LIBS="$LIBS -lbind"],
+                 [AC_CHECK_LIB([resolv],
+                         [res_query],
+                         [LIBS="$LIBS -lresolv"],
+                         [echo "cannot find resolver library"; exit 1;])
+                 ])
+         ],
+ 		[dnl Have to include resolv.h as res_query is sometimes defined as a macro
+ 				AC_MSG_CHECKING([for res_query in -lresolv (with resolv.h if present)])
+ 				saved_libs="$LIBS"
+ 				LIBS="-lresolv $LIBS"
+ 				AC_TRY_LINK([
+ 						#ifdef HAVE_RESOLV_H
+ 						#include <resolv.h>
+ 						#endif],
+ 						[res_query(0,0,0,0,0)],
+ 						[AC_MSG_RESULT(yes)
+ 								have_res_query=yes],
+ 						[AC_MSG_RESULT(no)
+ 								LIBS="$saved_libs"])
+         ])
+ 		
+fi		
 		
 		
 dnl [AC_CHECK_LIB(resolv, res_query)])
 
 # Checks for libraries.
diff -U 5 -r libspf2-1.2.5.orig/src/include/spf_dns.h libspf2-1.2.5/src/include/spf_dns.h
--- libspf2-1.2.5.orig/src/include/spf_dns.h	2004-08-29 10:59:33.000000000 -0400
+++ libspf2-1.2.5/src/include/spf_dns.h	2008-04-25 14:14:38.000000000 -0400
@@ -96,10 +96,19 @@
 #define	HOST_NOT_FOUND 	1		/* NXDOMAIN (authoritative answer)*/
 #define	TRY_AGAIN	2		/* SERVFAIL (no authoritative answer)*/
 #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;
 
 #include "spf_request.h"
diff -U 5 -r libspf2-1.2.5.orig/src/include/spf_response.h libspf2-1.2.5/src/include/spf_response.h
--- libspf2-1.2.5.orig/src/include/spf_response.h	2005-02-21 21:33:02.000000000 -0500
+++ libspf2-1.2.5/src/include/spf_response.h	2008-04-25 14:14:38.000000000 -0400
@@ -147,10 +147,14 @@
 ,	SPF_E_BAD_HOST_TLD		/* Hostname has a missing or invalid TLD */
 ,	SPF_E_MECH_AFTER_ALL	/* Mechanisms found after the \"all:\"
 								mechanism will be ignored */
 ,	SPF_E_INCLUDE_RETURNED_NONE	/* If an include recursive query returns none it's a perm error */
 ,	SPF_E_RECURSIVE			/* Recursive include */
+
+#ifdef SUPPORT_DNSSEC
+,	SPF_E_DNSSEC_FAILURE		/* DNSSEC validation failure */
+#endif
 } SPF_errcode_t;
 
 typedef
 struct SPF_error_struct
 {
diff -U 5 -r libspf2-1.2.5.orig/src/libspf2/spf_dns_resolv.c libspf2-1.2.5/src/libspf2/spf_dns_resolv.c
--- libspf2-1.2.5.orig/src/libspf2/spf_dns_resolv.c	2005-02-18 21:38:12.000000000 -0500
+++ libspf2-1.2.5/src/libspf2/spf_dns_resolv.c	2008-04-25 15:02:11.000000000 -0400
@@ -43,10 +43,14 @@
 
 #ifdef HAVE_PTHREAD_H
 # include <pthread.h>
 #endif
 
+#ifdef SUPPORT_DNSSEC
+#include <validator/validator.h>
+#endif
+
 #include "spf.h"
 #include "spf_dns.h"
 #include "spf_internal.h"
 #include "spf_dns_internal.h"
 #include "spf_dns_resolv.h"
@@ -59,20 +63,25 @@
     struct __res_state	res_state;
 #endif
 } SPF_dns_resolv_config_t;
 #endif
 
+#ifdef SUPPORT_DNSSEC
+# define SPF_h_errno h_errno
+#else
 #if HAVE_DECL_RES_NINIT
 # if 0
 #  define SPF_h_errno spfhook->res_state.res_h_errno
 # else
 #  define SPF_h_errno res_state->res_h_errno
 # endif
 #else
 # define SPF_h_errno h_errno
 #endif
+#endif
 
+#ifndef SUPPORT_DNSSEC
 static pthread_once_t	res_state_control = PTHREAD_ONCE_INIT;
 static pthread_key_t	res_state_key;
 
 static void
 SPF_dns_resolv_thread_term(void *arg)
@@ -84,11 +93,11 @@
 static void
 SPF_dns_resolv_init_key()
 {
 	pthread_key_create(&res_state_key, SPF_dns_resolv_thread_term);
 }
-
+#endif
 
 #if 0
 static inline SPF_dns_resolv_config_t *SPF_voidp2spfhook(void *hook)
 	{ return (SPF_dns_resolv_config_t *)hook; }
 static inline void *SPF_spfhook2voidp(SPF_dns_resolv_config_t *spfhook)
@@ -99,11 +108,11 @@
 static SPF_dns_rr_t *
 SPF_dns_resolv_lookup(SPF_dns_server_t *spf_dns_server,
 				const char *domain, ns_type rr_type, int should_cache)
 {
 #if 0
-    SPF_dns_resolv_config_t	*spfhook;
+    SPF_dns_resolv_config_t    *spfhook;
 #endif
     SPF_dns_rr_t			*spfrr;
 
     int		err;
     int		i;
@@ -128,20 +137,26 @@
     int		prio;
 
     int		rdlen;
     const u_char	*rdata, *rdata_end;
 
+#ifndef SUPPORT_DNSSEC
 	void				*res_spec;
 	struct __res_state	*res_state;
+#endif
 
 	SPF_ASSERT_NOTNULL(spf_dns_server);
 
 #if 0
-	spfhook = SPF_voidp2spfhook(spf_dns_server->hook);
+    spfhook = SPF_voidp2spfhook(spf_dns_server->hook);
 	SPF_ASSERT_NOTNULL(spfhook);
 #endif
+#ifdef SUPPORT_DNSSEC
+    val_status_t dnssec_status = VAL_INTERNAL_ERROR;
+#endif
 
+#ifndef SUPPORT_DNSSEC
 	res_spec = pthread_getspecific(res_state_key);
 	if (res_spec == NULL) {
 		res_state = (struct __res_state *)
 						malloc(sizeof(struct __res_state));
 		if (res_ninit(res_state) != 0) {
@@ -150,21 +165,32 @@
 		pthread_setspecific(res_state_key, (void *)res_state);
 	}
 	else {
 		res_state = (struct __res_state *)res_spec;
 	}
+#endif
 
     /*
      * try resolving the name
      */
+#ifdef SUPPORT_DNSSEC
+		
+	dns_len = val_res_query( NULL, domain, ns_c_in, rr_type, 
+                            response, sizeof(response), &dnssec_status );
+	if (dns_len >= 0) {
+		SPF_debugf( "val_res_query() returned dnssec_status = %s\n", 
+				    p_val_status( dnssec_status ) );
+	}
+#else
 #if HAVE_DECL_RES_NINIT
 	dns_len = res_nquery(res_state, domain, ns_c_in, rr_type,
 			 response, sizeof(response));
 #else
     dns_len = res_query(domain, ns_c_in, rr_type,
 			 response, sizeof(response));
 #endif
+#endif
 
 	if ( dns_len < 0 ) {
 		/* This block returns unconditionally. */
 		if ( spf_dns_server->debug )
 			SPF_debugf( "query failed: err = %d  %s (%d): %s",
@@ -173,17 +199,37 @@
 		if ((SPF_h_errno == HOST_NOT_FOUND) &&
 				(spf_dns_server->layer_below != NULL)) {
 			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);
 	}
 
     /*
      * 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);
 
     err = ns_initparse( response, dns_len, &ns_handle );
 
@@ -445,19 +491,27 @@
 	}
 
     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
+
     return spfrr;
 }
 
 
 static void
 SPF_dns_resolv_free(SPF_dns_server_t *spf_dns_server)
 {
 #if 0
-	SPF_dns_resolv_config_t	*spfhook;
+	SPF_dns_resolv_config_t *spfhook;
 #endif
 
 	SPF_ASSERT_NOTNULL(spf_dns_server);
 
 #if 0
@@ -481,14 +535,16 @@
 SPF_dns_resolv_new(SPF_dns_server_t *layer_below,
 				const char *name, int debug)
 {
 	SPF_dns_server_t		*spf_dns_server;
 #if 0
-	SPF_dns_resolv_config_t	*spfhook;
+	SPF_dns_resolv_config_t *spfhook;
 #endif
 
+#ifndef SUPPORT_DNSSEC
 	pthread_once(&res_state_control, SPF_dns_resolv_init_key);
+#endif
 
     spf_dns_server = malloc(sizeof(SPF_dns_server_t));
     if ( spf_dns_server == NULL )
 		return NULL;
 	memset(spf_dns_server, 0, sizeof(SPF_dns_server_t));
diff -U 5 -r libspf2-1.2.5.orig/src/libspf2/spf_dns_rr.c libspf2-1.2.5/src/libspf2/spf_dns_rr.c
--- libspf2-1.2.5.orig/src/libspf2/spf_dns_rr.c	2005-02-21 20:42:34.000000000 -0500
+++ libspf2-1.2.5/src/libspf2/spf_dns_rr.c	2008-04-25 14:14:38.000000000 -0400
@@ -43,11 +43,11 @@
 SPF_dns_rr_t *
 SPF_dns_rr_new_nxdomain(SPF_dns_server_t *spf_dns_server,
 				const char *domain)
 {
 	return SPF_dns_rr_new_init(spf_dns_server,
-					domain, ns_t_any, 0, NXDOMAIN);
+					domain, ns_t_any, 0, HOST_NOT_FOUND);
 }
 
 SPF_dns_rr_t *
 SPF_dns_rr_new_init(SPF_dns_server_t *spf_dns_server,
 				const char *domain,
diff -U 5 -r libspf2-1.2.5.orig/src/libspf2/spf_get_exp.c libspf2-1.2.5/src/libspf2/spf_get_exp.c
--- libspf2-1.2.5.orig/src/libspf2/spf_get_exp.c	2004-10-19 10:20:17.000000000 -0400
+++ libspf2-1.2.5/src/libspf2/spf_get_exp.c	2008-04-25 14:14:38.000000000 -0400
@@ -162,10 +162,17 @@
 
 	case TRY_AGAIN:
 		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;
 
 	default:
 		SPF_warning("unknown DNS lookup error code");
diff -U 5 -r libspf2-1.2.5.orig/src/libspf2/spf_interpret.c libspf2-1.2.5/src/libspf2/spf_interpret.c
--- libspf2-1.2.5.orig/src/libspf2/spf_interpret.c	2005-02-21 22:41:27.000000000 -0500
+++ libspf2-1.2.5/src/libspf2/spf_interpret.c	2008-04-25 14:17:52.000000000 -0400
@@ -252,10 +252,18 @@
 	size_t			 buflen = SPF_RECEIVED_SPF_SIZE;
 	char			*buf_value;
 	
 	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);
 	spf_server = spf_request->spf_server;
 	SPF_ASSERT_NOTNULL(spf_server);
@@ -326,10 +334,61 @@
 			p += snprintf( p, p_end - p, " problem=%s;", c_results.err_msg );
 			if ( p_end - p <= 0 ) break;
 		}
 	#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? */
 	} while(0);
 
@@ -745,10 +804,19 @@
 				SPF_dns_rr_free(rr_a);
 				SPF_FREE_LOOKUP_DATA();
 				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++) {
 				if ( rr_a->rr_type != fetch_ns_type )
 					continue;
 
 				if (spf_request->client_ver == AF_INET) {
@@ -785,10 +853,18 @@
 				SPF_dns_rr_free(rr_mx);
 				SPF_FREE_LOOKUP_DATA();
 				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
 			max_mx = rr_mx->num_rr;
 			if ( max_mx > spf_server->max_dns_mx )
 				max_mx = spf_server->max_dns_mx;
 			if ( max_mx > SPF_MAX_DNS_MX )
 				max_mx = SPF_MAX_DNS_MX;
@@ -813,10 +889,24 @@
 					SPF_dns_rr_free(rr_a);
 					SPF_FREE_LOOKUP_DATA();
 					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++ ) {
 					if ( rr_a->rr_type != fetch_ns_type )
 						continue;
 
 					if ( spf_request->client_ver == AF_INET )
@@ -888,10 +978,17 @@
 						SPF_dns_rr_free(rr_a);
 						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'.",
+								       rr_ptr->rr[i]->ptr );
+					}
+#endif
 					for( j = 0; j < rr_a->num_rr; j++ ) {
 						if ( spf_server->debug ) {
 							INET_NTOP( AF_INET, &rr_a->rr[j]->a.s_addr,
 											ip4_buf, sizeof(ip4_buf));
 							SPF_debugf( "%d: %d:  found %s",
@@ -949,10 +1046,17 @@
 						SPF_dns_rr_free(rr_aaaa);
 						SPF_FREE_LOOKUP_DATA();
 						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++ ) {
 						if ( spf_server->debug ) {
 							INET_NTOP(AF_INET6, &rr_aaaa->rr[j]->aaaa.s6_addr,
 											ip6_buf, sizeof(ip6_buf));
 							SPF_debugf( "%d: %d:  found %s",
@@ -1067,10 +1171,36 @@
 				/* Set everything up properly again. */
 				spf_response_subr = spf_response;
 				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:
 						/* Pass */
 						SPF_FREE_LOOKUP_DATA();
@@ -1150,10 +1280,17 @@
 
 			if( rr_a->herrno == TRY_AGAIN ) {
 				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_FREE_LOOKUP_DATA();
 				return DONE_MECH(mech->prefix_type);
 			}
 
diff -U 5 -r libspf2-1.2.5.orig/src/libspf2/spf_server.c libspf2-1.2.5/src/libspf2/spf_server.c
--- libspf2-1.2.5.orig/src/libspf2/spf_server.c	2005-02-18 22:52:58.000000000 -0500
+++ libspf2-1.2.5/src/libspf2/spf_server.c	2008-04-25 14:36:34.000000000 -0400
@@ -277,12 +277,11 @@
 	switch( rr_txt->herrno ) {
 		case HOST_NOT_FOUND:
 			SPF_dns_rr_free(rr_txt);
 			spf_response->result = SPF_RESULT_NONE;
 			spf_response->reason = SPF_REASON_FAILURE;
-			return SPF_response_add_error(spf_response, 
-SPF_E_NOT_SPF,
+			return SPF_response_add_error(spf_response, SPF_E_NOT_SPF,
 					"Host '%s' not found.", domain);
 			break;
 
 		case NO_DATA:
 			SPF_dns_rr_free(rr_txt);
@@ -299,10 +298,17 @@
 			break;
 
 		case NETDB_SUCCESS:
 			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:
 			SPF_dns_rr_free(rr_txt);
 			return SPF_response_add_error(spf_response, SPF_E_DNS_ERROR,
 					"Unknown DNS failure for '%s': %d.",
 					domain, rr_txt->herrno);
diff -U 5 -r libspf2-1.2.5.orig/src/libspf2/spf_strerror.c libspf2-1.2.5/src/libspf2/spf_strerror.c
--- libspf2-1.2.5.orig/src/libspf2/spf_strerror.c	2005-02-21 21:34:21.000000000 -0500
+++ libspf2-1.2.5/src/libspf2/spf_strerror.c	2008-04-25 14:14:38.000000000 -0400
@@ -160,10 +160,15 @@
 
 	case SPF_E_RECURSIVE:
 	return "include: or redirect= caused unlimited recursion";
 	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;
     }