File: libspf2-dnssec.patch

package info (click to toggle)
dnssec-tools 1.13-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 16,064 kB
  • sloc: perl: 44,399; ansic: 31,547; cpp: 21,306; sh: 15,813; xml: 2,113; makefile: 1,390; pascal: 836; python: 290; csh: 11
file content (542 lines) | stat: -rw-r--r-- 17,659 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
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;