Sophie

Sophie

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

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

diff -U 5 -Nar spfmilter-1.0.8.orig/config.h.in spfmilter-1.0.8/config.h.in
--- spfmilter-1.0.8.orig/config.h.in	2004-07-13 16:51:53.000000000 -0400
+++ spfmilter-1.0.8/config.h.in	2008-04-26 00:21:26.000000000 -0400
@@ -22,10 +22,13 @@
 #undef HAVE_INET_NTOP
 
 /* 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 `milter' library (-lmilter). */
 #undef HAVE_LIBMILTER
 
 /* Define to 1 if you have the `nsl' library (-lnsl). */
 #undef HAVE_LIBNSL
@@ -40,10 +43,16 @@
 #undef HAVE_LIBSOCKET
 
 /* Define to 1 if you have the `spf2' library (-lspf2). */
 #undef HAVE_LIBSPF2
 
+/* 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 <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #undef HAVE_NETINET_IN_H
@@ -121,13 +130,19 @@
 #undef SIZEOF_UNSIGNED_LONG
 
 /* 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
 
+/* libspf2 version 1.2.x */
+#undef USE_LIBSPF2_1_2_X
+
 /* Version number of package */
 #undef VERSION
 
 /* Define to 1 if your processor stores words with the most significant byte
    first (like Motorola and SPARC, unlike Intel and VAX). */
diff -U 5 -Nar spfmilter-1.0.8.orig/configure.ac spfmilter-1.0.8/configure.ac
--- spfmilter-1.0.8.orig/configure.ac	2004-08-10 06:24:57.000000000 -0400
+++ spfmilter-1.0.8/configure.ac	2008-04-26 00:21:26.000000000 -0400
@@ -52,28 +52,112 @@
 AC_CHECK_LIB(pthread, pthread_create)
 
 AC_CHECK_FUNC(socket, ,
 	AC_CHECK_LIB(socket, socket, ,
 		AC_CHECK_LIB(nsl, socket)))
-AC_CHECK_FUNCS(inet_ntop, ,
+
+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)
+
+   AC_CHECK_FUNCS(inet_ntop, ,
+	AC_CHECK_LIB(nsl, inet_ntop, ,
+		AC_CHECK_LIB(socket, inet_ntop)))
+
+   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,
+	[  --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)
+
+   AC_CHECK_FUNCS(inet_ntop, ,
 	AC_CHECK_LIB(nsl, inet_ntop, ,
 		AC_CHECK_LIB(socket, inet_ntop, ,
 			AC_CHECK_LIB(resolv, inet_ntop))))
-AC_CHECK_FUNC(gethostbyname, ,
+   AC_CHECK_FUNC(gethostbyname, ,
 	AC_CHECK_LIB(nsl, gethostbyname, ,
 		AC_CHECK_LIB(socket, gethostbyname, ,
 			AC_CHECK_LIB(resolv, gethostbyname))))
+fi
 
 AC_CHECK_HEADER(spf2/spf.h, , [
 	echo "libspf2 is required to build this program."
 	exit 1;
+], [
+#include <netinet/in.h>
 ])
-AC_CHECK_LIB(spf2, SPF_destroy_config, , [
-	echo "libspf2 is required to build this program."
-	exit 1;
+
+dnl Check for newer version (1.2.x) of libspf2 header files
+AC_CHECK_HEADER(spf2/spf_server.h, [AC_DEFINE([USE_LIBSPF2_1_2_X], [], [libspf2 version 1.2.x])], , [
+#include <netinet/in.h>
 ])
 
+AC_CHECK_LIB(spf2, SPF_destroy_config, ,
+        AC_CHECK_LIB(spf2, SPF_server_new, , [
+	     echo "libspf2 is required to build this program."
+	     exit 1;
+]))
+
 AC_CHECK_HEADER(libmilter/mfapi.h, , [
 	echo "sendmail's libmilter is required to build this program."
 	exit 1;
 ])
 AC_CHECK_LIB(milter, smfi_main, , [
diff -U 5 -Nar spfmilter-1.0.8.orig/spfmilter.c spfmilter-1.0.8/spfmilter.c
--- spfmilter-1.0.8.orig/spfmilter.c	2004-08-10 06:14:59.000000000 -0400
+++ spfmilter-1.0.8/spfmilter.c	2008-04-26 00:37:20.000000000 -0400
@@ -25,26 +25,29 @@
 ** SUCH DAMAGE.
 **
 ** For commentary on this license please see http://www.acme.com/license.html
 */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#include "port.h"
+#endif
 
-#if ! ( defined(USE_LIBSPF) || defined(USE_LIBSPF2) )
+#if ! ( defined(USE_LIBSPF) || defined(USE_LIBSPF2) || defined(USE_LIBSPF2_1_2_X))
 #define USE_LIBSPF2	/* default library is libspf2 */
 #endif
 
 #if defined(USE_LIBSPF) && defined(USE_LIBSPF2)
 #error "both USE_LIBSPF and USE_LIBSPF2 are defined - please pick one"
 #endif
 
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#else
-#include "port.h"
+#ifdef USE_LIBSPF2_1_2_X
+#undef USE_LIBSPF2
 #endif
 
+
 #ifdef STDC_HEADERS
 #include <stdio.h>
 #include <stdlib.h>
 #include <syslog.h>
 #include <errno.h>
@@ -104,10 +107,11 @@
 
 
 /* Defines. */
 
 #define HEADER_NAME "Received-SPF"
+#define PID_FILE "/var/run/spfmilter.pid"
 
 #define SPFMILTER_RESULT_PASS 0
 #define SPFMILTER_RESULT_FAIL 1
 #define SPFMILTER_RESULT_SOFTFAIL 2
 #define SPFMILTER_RESULT_NEUTRAL 3
@@ -119,10 +123,15 @@
 #define SPFMILTER_ACTION_UNKNOWN 0
 #define SPFMILTER_ACTION_REJECT 1
 #define SPFMILTER_ACTION_MARK 2
 #define SPFMILTER_ACTION_TEMPFAIL 3
 
+#ifdef SUPPORT_DNSSEC
+#define SPFMILTER_DNSSEC_POLICY_IGNORE 0
+#define SPFMILTER_DNSSEC_POLICY_WARN 1
+#define SPFMILTER_DNSSEC_POLICY_REJECT 2
+#endif
 
 /* Structs. */
 
 
 /* Fallback list. */
@@ -232,10 +241,15 @@
 static int lib_do_check_final( lib_data_t* ld );
 static int lib_get_result( lib_data_t* ld );
 static const char* lib_get_reason( lib_data_t* ld );
 static const char* lib_get_explanation( lib_data_t* ld );
 static const char* lib_get_error( lib_data_t* ld );
+#ifdef SUPPORT_DNSSEC
+static const char* lib_get_error_msg( lib_data_t* ld );
+static const size_t lib_get_num_errors( lib_data_t* ld );
+static const char** lib_get_error_msgs( lib_data_t* ld );
+#endif
 static void lib_fini_message_data( lib_data_t* ld );
 static void lib_fini_connection_data( lib_data_t* ld );
 static void lib_fini_fallback( lib_fallback_t* lf );
 static void lib_fini( void );
 
@@ -252,10 +266,14 @@
 static int markonly;
 static int debug;
 static char* local_hostname;
 static int local_hostname_len;
 
+#ifdef SUPPORT_DNSSEC
+static int dnssec_policy;
+#endif
+
 static int header_name_len;
 
 static struct smfiDesc smfilter = {
     "SPF",				/* filter name */
     SMFI_VERSION,			/* version code -- do not change */
@@ -285,20 +303,29 @@
     { "user",			required_argument,	NULL,	'u', },
     { "pidfile",		required_argument,	NULL,	'p', },
     { "nodaemon",		no_argument,		NULL,	'X', },
     { "help",			no_argument,		NULL,	'h', },
     { "debug",			optional_argument,	NULL,	'd', },
+
+#ifdef SUPPORT_DNSSEC
+    { "dnssec_policy",          required_argument,      NULL,   's', },
+#endif
+
     { 0, 0, 0, 0 },
 };
 #define DOC_LONGOPT(l, v, t, p1) \
     do { \
 	(void) fprintf( stderr, "    --%s%c%s%*s" t "\n", l, (v ? '=' : ' '),  (v ? v : ""), p1, "" ); \
     } while( 0 )
 #else
 #define DOC_LONGOPT(l, v, t, p1) do { } while( 0 )
 #endif
+#ifdef SUPPORT_DNSSEC
+static const char* shortopts = "l:tg:f:w:re:mu:p:Xhd:s:";
+#else
 static const char* shortopts = "l:tg:f:w:re:mu:p:Xhd::";
+#endif
 
 #define DOC_OPT(s, l, v, t, p0, p1) \
     do { \
 	(void) fprintf( stderr, "    -%c%c%s%*s" t "\n", s, (v ? ' ' : ' '), (v ? v : ""), p0, "" ); \
 	DOC_LONGOPT(l, v, t, p1); \
@@ -327,14 +354,18 @@
     whitelist_filename = (char*) 0;
     recipientmx = 0;
     explanation_str = (char*) 0;
     markonly = 0;
     user = (char*) 0;
-    pidfile = (char*) 0;
+    pidfile = PID_FILE;
     nodaemon = 0;
     debug = 0;
 
+#ifdef SUPPORT_DNSSEC
+    dnssec_policy = SPFMILTER_DNSSEC_POLICY_IGNORE;
+#endif
+
     /* Figure out the program's name. */
     argv0 = strrchr( argv[0], '/' );
     if ( argv0 != (char*) 0 )
 	++argv0;
     else
@@ -394,10 +425,41 @@
 		if ( optarg )
 		    debug = atoi( optarg );
 		else
 		    debug = 1;
 		break;
+
+#ifdef SUPPORT_DNSSEC
+	    case 's':
+	        if ( optarg )
+		    {
+		    if ( strncasecmp( optarg, "ignore", 6 ) == 0 )
+			{
+		        if ( debug )
+	 		    printf( "DNSSEC policy = ignore\n" );
+		        dnssec_policy = SPFMILTER_DNSSEC_POLICY_IGNORE;
+			}
+		    else if ( strncasecmp( optarg, "warn", 4 ) == 0 )
+			{
+		        if ( debug )
+	 		    printf( "DNSSEC policy = warn\n" );
+		        dnssec_policy = SPFMILTER_DNSSEC_POLICY_WARN;
+			}
+		    else if ( strncasecmp( optarg, "reject", 6 ) == 0 )
+			{
+		        if ( debug )
+	 		    printf( "DNSSEC policy = reject\n" );
+		        dnssec_policy = SPFMILTER_DNSSEC_POLICY_REJECT;
+			}
+		    else
+			{
+		        fprintf( stderr, "Unrecognized option argument '%s'\n", optarg );
+			}
+		}
+		break;
+#endif
+
 	    default:
 		(void) fprintf( stderr, "Unrecognised option '%c'\n", c );
 		exit( 1 );
 	    }
 	}
@@ -463,10 +525,15 @@
     DOC_OPT( 'u', "user", "<user|uid>", "Run as specified user or UID.", 10, 16 );
     DOC_OPT( 'p', "pidfile", "<filename>", "Write the process i.d. to the specified file.", 10, 16 );
     DOC_OPT( 'X', "nodaemon", (char*) 0, "Do not fork into the background.", 20, 26 );
     DOC_OPT( 'h', "help", (char*) 0, "Show this help.", 20, 26 );
     DOC_OPT( 'd', "debug", "[<int>]", "Enable debugging to syslog.", 13, 18 );
+
+#ifdef SUPPORT_DNSSEC
+    DOC_OPT( 's', "dnssec_policy", "<ignore|warn|reject>", "Action in the event of DNSSEC validation failure", 16, 3 );
+#endif
+
     }
 
 
 static void
 init_fallback( const char* fallback_filename, const char* guess_str )
@@ -1286,10 +1353,16 @@
     {
     connection_data_t* cd;
     const char* exp;
     char exp_escaped[1000];
 
+#ifdef SUPPORT_DNSSEC
+    const char* errmsg;
+    char exp_errmsg[1000];
+    char err_reply[2048];
+#endif
+
     cd = (connection_data_t*) smfi_getpriv( ctx );
 
     switch ( cd->result )
 	{
 	case SPFMILTER_RESULT_PASS:
@@ -1316,11 +1389,26 @@
 	    syslog( LOG_INFO, "rejecting mail from [%s] - %s", cd->ip_str, lib_get_reason( cd->lib_data ) );
 	    if ( exp != (char*) 0 )
 		escape_percents( exp, exp_escaped, sizeof(exp_escaped) );
 	    else
 		(void) strncpy( exp_escaped, "rejected by spfmilter", sizeof(exp_escaped) - 1 );
+
+#ifdef SUPPORT_DNSSEC
+	    strncpy( err_reply, exp_escaped, sizeof(err_reply) - 1 );
+
+	    errmsg = lib_get_error_msg( cd->lib_data );
+	    if ( errmsg != (char*) 0 )
+		{
+	        escape_percents( errmsg, exp_errmsg, sizeof(exp_errmsg) );
+		strncpy( err_reply + strlen( exp_escaped ), ".  Error: ", sizeof(err_reply) - strlen( exp_escaped ) - 1 );
+		strncpy( err_reply + strlen( err_reply ), exp_errmsg, sizeof(err_reply) - strlen( err_reply ) - 1 );
+		}
+
+	    smfi_setreply( ctx, "550", "5.7.1", err_reply );
+#else
 	    smfi_setreply( ctx, "550", "5.7.1", exp_escaped );
+#endif
 	    fini_message_data( cd );
 	    return SMFIS_REJECT;
 
 	case SPFMILTER_ACTION_TEMPFAIL:
 	    syslog( LOG_INFO, "temporarily failing mail from [%s] - %s", cd->ip_str, lib_get_error( cd->lib_data ) );
@@ -1441,10 +1529,18 @@
 static void
 build_header( connection_data_t* cd, char* header, int header_size, const char* reason )
     {
     int len;
 
+#ifdef SUPPORT_DNSSEC
+    int i;
+    char *err_msg;
+    char **err_msgs;
+    size_t num_errs;
+    int first_err;
+#endif
+
     (void) snprintf( header, header_size, "%s", result_str( cd->result ) );
     len = strlen( header );
     if ( reason != (char*) 0 )
 	{
 	(void) snprintf( &header[len], header_size - len, " (%s)", reason );
@@ -1469,10 +1565,86 @@
 	{
 	(void) snprintf( &header[len], header_size - len, " envelope-from=%s;", cd->from );
 	len = strlen( header );
 	}
     /*!!! Do something about the problem= field. */
+
+#ifdef SUPPORT_DNSSEC
+    err_msg = (char *) ( lib_get_error_msg( cd->lib_data ) );
+    err_msgs = (char **) ( lib_get_error_msgs( cd->lib_data ) );
+    num_errs = lib_get_num_errors( cd->lib_data );
+    first_err = 1;
+    if ( ( err_msg != (char*) 0 ) && ( strstr( err_msg, "DNSSEC" ) == NULL ) )
+        {
+	(void) snprintf( &header[len], header_size - len, " problem=%s;", err_msg );
+	first_err = 0;
+	len = strlen( header );
+	}
+
+    for( i = 0; i < num_errs; i++ )
+	{
+	if( ( err_msgs[i] != NULL ) &&
+	    ( strstr( err_msgs[i], "DNSSEC" ) == NULL ) &&
+	    ( ( err_msg == NULL ) || ( strcmp( err_msgs[i], err_msg ) != 0 ) )
+	  )
+	    {
+	    if ( first_err == 1 )
+		{
+		(void) snprintf( &header[len], header_size - len, " problem=%s;", err_msgs[i] );
+		first_err = 0;
+		}
+	    else
+		{
+	        (void) snprintf( &header[len], header_size - len, "%s;", err_msgs[i] );
+		}
+	    len = strlen( header );
+	    }
+	}
+    
+    first_err = 1;
+    for( i = 0; i < num_errs; i++ )
+	{
+	if ( ( err_msgs[i] != NULL ) && ( strstr( err_msgs[i], "DNSSEC") != NULL ) )
+	    {
+	    if ( first_err == 1 )
+		{
+		(void) snprintf( &header[len], header_size - len,
+				 " x-dnssec=\"fail (%s", err_msgs[i] );
+		first_err = 0;
+		}
+	    else
+		{
+		(void) snprintf( &header[len], header_size - len,
+				 ", %s", err_msgs[i] );
+		}
+	    len = strlen(header);
+	    }
+	}
+
+    if ( first_err == 1 )
+	{
+	if ( ( dnssec_policy == SPFMILTER_DNSSEC_POLICY_IGNORE ) 
+	     || ( cd->result == SPFMILTER_RESULT_NONE ) )
+	    {
+	    (void) snprintf( &header[len], header_size - len,
+			     " x-dnssec=\"none\";" );
+	    len = strlen( header );
+	    }
+	else
+	    {
+	    (void) snprintf( &header[len], header_size - len,
+			     " x-dnssec=\"pass\";" );
+	    len = strlen( header );
+	    }
+	}
+    else
+	{
+	(void) snprintf( &header[len], header_size - len, ")\";" );
+	len = strlen( header );
+	}
+#endif
+
     (void) snprintf( &header[len], header_size - len, " x-software=%s %s %s;", SPFMILTER_PROGRAM, SPFMILTER_VERSION, SPFMILTER_URL );
     }
 
 
 static connection_data_t*
@@ -1747,10 +1919,33 @@
     {
     return ld->peer_info->error;
     }
 
 
+#ifdef SUPPORT_DNSSEC
+static const char*
+lib_get_error_msg( lib_data_t* ld )
+    {
+    return lib_get_error( ld );
+    }
+
+
+static const size_t
+lib_get_num_errors( lib_data_t* ld )
+    {
+    return 0;
+    }
+
+
+static const char**
+lib_get_error_msgs( lib_data_t* ld )
+    {
+    return NULL;
+    }
+
+#endif
+
 static void
 lib_fini_message_data( lib_data_t* ld )
     {
     }
 
@@ -1783,11 +1978,11 @@
 #endif /* USE_LIBSPF */
 
 
 #ifdef USE_LIBSPF2
 
-/* Libspf2 data and routines. */
+/* Libspf2 Version 1.0.X and lower versions data and routines. */
 
 
 #include <spf2/spf.h>
 #include <spf2/spf_dns_resolv.h>
 #include <spf2/spf_dns_cache.h>
@@ -2060,22 +2255,52 @@
 
 
 static int
 lib_get_result( lib_data_t* ld )
     {
+    int retval;
     /* Convert libspf2 result to spfmilter result. */
     switch ( ld->output.result )
 	{
-	case SPF_RESULT_PASS: return SPFMILTER_RESULT_PASS;
-	case SPF_RESULT_FAIL: return SPFMILTER_RESULT_FAIL;
-	case SPF_RESULT_SOFTFAIL: return SPFMILTER_RESULT_SOFTFAIL;
-	case SPF_RESULT_NEUTRAL: return SPFMILTER_RESULT_NEUTRAL;
-	case SPF_RESULT_UNKNOWN: return SPFMILTER_RESULT_UNKNOWN;
-	case SPF_RESULT_ERROR: return SPFMILTER_RESULT_ERROR;
-	case SPF_RESULT_NONE: return SPFMILTER_RESULT_NONE;
-	default: return -1;
-	}
+	case SPF_RESULT_PASS:    retval = SPFMILTER_RESULT_PASS;     break;
+	case SPF_RESULT_FAIL:    retval = SPFMILTER_RESULT_FAIL;     break;
+	case SPF_RESULT_SOFTFAIL:retval = SPFMILTER_RESULT_SOFTFAIL; break;
+	case SPF_RESULT_NEUTRAL: retval = SPFMILTER_RESULT_NEUTRAL;  break;
+	case SPF_RESULT_UNKNOWN: retval = SPFMILTER_RESULT_UNKNOWN;  break;
+	case SPF_RESULT_ERROR:   retval = SPFMILTER_RESULT_ERROR;    break;
+	case SPF_RESULT_NONE:    retval = SPFMILTER_RESULT_NONE;     break;
+	default:                 retval = -1;                        break;
+	}
+
+#ifdef SUPPORT_DNSSEC
+        /* Check if there was a DNSSEC validation failure */
+        if ( dnssec_policy == SPFMILTER_DNSSEC_POLICY_REJECT )
+	    {
+	    int i;
+	    int num_errs;
+	    const char **err_msgs;
+
+	    num_errs = lib_get_num_errors( ld );
+	    err_msgs = lib_get_error_msgs( ld );
+
+	    for ( i = 0; i < num_errs; i++ )
+		{
+		if ( err_msgs[i] )
+		    {
+		    if ( strstr( err_msgs[i], "DNSSEC" ) != NULL )
+			{
+			if ( debug )
+			    printf( "spfmilter: DNSSEC validation failure occured.  Rejecting mail.\n" );
+			retval = SPFMILTER_RESULT_FAIL;
+			break;
+			}
+		    }
+		}
+	    }
+#endif
+
+	return retval;
     }
 
 
 static const char*
 lib_get_reason( lib_data_t* ld )
@@ -2096,10 +2321,33 @@
     {
     return SPF_strerror( ld->output.err );
     }
 
 
+#ifdef SUPPORT_DNSSEC
+static const char*
+lib_get_error_msg( lib_data_t* ld )
+    {
+    return  ld->output.err_msg ;
+    }
+
+
+static const size_t
+lib_get_num_errors( lib_data_t* ld )
+    {
+    return ld->output.num_errs;
+    }
+
+
+static const char**
+lib_get_error_msgs( lib_data_t* ld )
+    {
+    return (const char**) (ld->output.err_msgs);
+    }
+
+#endif
+
 static void
 lib_fini_message_data( lib_data_t* ld )
     {
     if ( ld->from != (char*) 0 )
 	{
@@ -2201,11 +2449,11 @@
 
     for ( r = 0; r < max_resolvers; ++r )
 	if ( resolvers[r].initialized )
 	    {
 	    SPF_dns_destroy_config_cache( resolvers[r].spfdcid );
-	    SPF_dns_destroy_config_resolv( resolvers[r].spfdcid_r );
+		SPF_dns_destroy_config_resolv( resolvers[r].spfdcid_r );
 	    }
     pthread_mutex_destroy( &resolver_mutex );
     }
 
 
@@ -2257,11 +2505,11 @@
 
     /* Is it initialized? */
     if ( ! resolvers[r].initialized )
 	{
 	/* Create the DNS objects. */
-	resolvers[r].spfdcid_r = SPF_dns_create_config_resolv( (SPF_dns_config_t) 0, debug );
+	    resolvers[r].spfdcid_r = SPF_dns_create_config_resolv( (SPF_dns_config_t) 0, debug );
 	if ( resolvers[r].spfdcid_r == (SPF_dns_config_t) 0 )
 	    {
 	    syslog( LOG_ERR, "SPF_dns_create_config_resolv() failed" );
 	    free_resolver( r );
 	    return -1;
@@ -2297,5 +2545,373 @@
     --num_resolvers_inuse;
     pthread_mutex_unlock( &resolver_mutex );
     }
 
 #endif /* USE_LIBSPF2 */
+
+
+#ifdef USE_LIBSPF2_1_2_X
+
+/* Libspf2 Version 1.2.X data and routines. */
+
+#include <spf2/spf.h>
+
+static SPF_server_t   *spf_server;
+static SPF_request_t  *spf_localpolicy_requestp;
+static SPF_response_t *spf_localpolicy_responsep;
+static SPF_request_t  *spf_explanation_requestp;
+static SPF_response_t *spf_explanation_responsep;
+
+struct lib_fallback_s {
+    SPF_response_t *responsep;
+    SPF_request_t *requestp;
+};
+
+struct lib_data_s {
+    SPF_server_t *spf_server;
+    char *from;
+    SPF_response_t *responsep;
+    SPF_request_t *requestp;
+    int got_response;
+    char **err_msgs;
+};
+
+static int lib_init( void )
+{
+	spf_server = SPF_server_new( SPF_DNS_RESOLV, debug );
+    if (spf_server == NULL)
+	{
+	fprintf( stderr, "%s: SPF_server_new() failed\n", argv0 );
+	return 0;
+	}
+
+    if (localpolicy_str != NULL)
+	{
+	spf_localpolicy_requestp = SPF_request_new (spf_server);
+	spf_localpolicy_responsep = SPF_response_new(spf_localpolicy_requestp);
+	if (SPF_server_set_localpolicy(spf_server, localpolicy_str,
+				       trustedforwarders,
+				       &spf_localpolicy_responsep))
+	    {
+	    fprintf( stderr, "%s: error setting local policy - %s\n", argv0,
+		     localpolicy_str);
+	    return 0;
+	    }
+	}
+
+    if (explanation_str != NULL)
+	{
+	spf_explanation_requestp = SPF_request_new (spf_server);
+	spf_explanation_responsep = SPF_response_new(spf_explanation_requestp);
+	if (SPF_server_set_explanation(spf_server, explanation_str,
+				       &spf_explanation_responsep))
+	    {
+	    fprintf( stderr, "%s: error setting explanation - %s\n", argv0,
+		     explanation_str);
+	    return 0;
+	    }
+	}
+
+    return 1;
+}
+
+static lib_fallback_t* lib_init_fallback( const char* str )
+{
+    lib_fallback_t *lf;
+
+    lf = (lib_fallback_t*) malloc (sizeof(lib_fallback_t));
+    if (lf == NULL)
+	{
+	return NULL;
+	}
+
+    lf->requestp = SPF_request_new(spf_server);
+    lf->responsep = SPF_response_new(lf->requestp);
+
+    if (SPF_server_set_localpolicy(spf_server, str, trustedforwarders,
+				   &lf->responsep))
+	{
+	
+	fprintf( stderr, "%s: error setting fallback - %s\n", argv0,
+		 str);
+	free(lf);
+	return NULL;
+	}
+    
+    return lf;
+}
+
+static int lib_set_local_hostname( lib_data_t* ld )
+{
+    if (SPF_server_set_rec_dom (spf_server, local_hostname))
+	{
+	return 0;
+	}
+    
+    return 1;
+}
+
+static lib_data_t* lib_init_connection_data( void )
+{
+    lib_data_t* ld;
+
+    ld = (lib_data_t*) malloc( sizeof(lib_data_t) );
+    if ( ld == (lib_data_t*) 0 )
+	return (lib_data_t*) 0;
+
+    /* Create the per-connection server object creating a new one */
+	ld->spf_server = SPF_server_new( SPF_DNS_RESOLV, debug );
+    ld->from = NULL;
+    ld->got_response = 0;
+    ld->requestp = SPF_request_new(ld->spf_server);
+    ld->responsep = SPF_response_new(ld->requestp);
+    ld->err_msgs = NULL;
+
+    return ld;
+}
+
+static int lib_init_message_data( lib_data_t* ld )
+{
+    ld->from = NULL;
+    return 1;
+}
+
+static int lib_set_ipv4( lib_data_t* ld,
+			 struct in_addr ipv4_addr,
+			 char* ipv4_str )
+{
+    SPF_request_set_ipv4(ld->requestp, ipv4_addr);
+    SPF_request_set_ipv4_str(ld->requestp, ipv4_str);
+    return 1;
+}
+
+static int lib_set_ipv6( lib_data_t* ld,
+			 struct in6_addr ipv6_addr,
+			 char* ipv6_str )
+{
+    SPF_request_set_ipv6(ld->requestp, ipv6_addr);
+    SPF_request_set_ipv6_str(ld->requestp, ipv6_str);
+    return 1;
+}
+
+static int lib_set_helo_hostname( lib_data_t* ld, char* helo_hostname )
+{
+    SPF_request_set_helo_dom(ld->requestp, helo_hostname);
+    return 1;
+}
+
+static int lib_set_from( lib_data_t* ld, const char* from )
+{
+    SPF_request_set_env_from(ld->requestp, from);
+    return 1;
+}
+
+static int lib_do_check( lib_data_t* ld, const char* from )
+{
+    int retval;
+    lib_set_from(ld, from);
+    if ((retval = SPF_request_query_mailfrom(ld->requestp, &ld->responsep))
+	!= SPF_E_SUCCESS)
+	{
+	fprintf(stderr, "Error in lib_do_check(): SPF_request_query_mailfrom() returned %d\n", retval);
+	}
+
+    return 1;
+}
+
+static int lib_do_check_recipient( lib_data_t* ld, const char* to )
+{
+    if(SPF_request_query_rcptto(ld->requestp, &ld->responsep, to)
+	== SPF_E_SUCCESS) {
+	return 1;
+    }
+    else {
+	return 1;
+    }
+}
+
+static int lib_do_check_final( lib_data_t* ld )
+{
+    if (SPF_request_query_mailfrom(ld->requestp, &ld->responsep)
+	== SPF_E_SUCCESS) {
+	return 1;
+    }
+    else {
+	return 1;
+    }
+}
+
+static int lib_get_result( lib_data_t* ld )
+{
+    SPF_result_t res = SPF_response_result(ld->responsep);
+    int retval;
+    /* Convert libspf result to spfmilter result. */
+    switch ( res )
+	{
+	case SPF_RESULT_NEUTRAL:
+	    if (debug)
+		printf("libspf2 returned SPF_RESULT_NEUTRAL\n");
+	    retval = SPFMILTER_RESULT_NEUTRAL;
+	    break;
+
+	case SPF_RESULT_PASS:
+	    if (debug)
+		printf("libspf2 returned SPF_RESULT_PASS\n");
+	    retval = SPFMILTER_RESULT_PASS;
+	    break;
+
+	case SPF_RESULT_FAIL:
+	    if (debug)
+		printf("libspf2 returned SPF_RESULT_FAIL\n");
+	    retval = SPFMILTER_RESULT_FAIL;
+	    break;
+
+	case SPF_RESULT_SOFTFAIL:
+	    if (debug)
+		printf("libspf2 returned SPF_RESULT_SOFTFAIL\n");
+	    retval = SPFMILTER_RESULT_SOFTFAIL;
+	    break;
+
+	case SPF_RESULT_NONE:
+	    if (debug)
+		printf("libspf2 returned SPF_RESULT_NONE\n");
+	    retval = SPFMILTER_RESULT_NONE;
+	    break;
+
+	case SPF_RESULT_TEMPERROR:
+	    if (debug)
+		printf("libspf2 returned SPF_RESULT_TEMPERROR\n");
+	    retval = SPFMILTER_RESULT_ERROR;
+	    break;
+
+	case SPF_RESULT_PERMERROR:
+	    if (debug)
+		printf("libspf2 returned SPF_RESULT_PERMERROR\n");
+	    retval = SPFMILTER_RESULT_UNKNOWN;
+	    break;
+
+	default: retval = -1;
+	}
+
+#ifdef SUPPORT_DNSSEC
+        /* Check if there was a DNSSEC validation failure */
+        if ( dnssec_policy == SPFMILTER_DNSSEC_POLICY_REJECT )
+	    {
+	    int i;
+	    int num_errs;
+
+	    num_errs = lib_get_num_errors( ld );
+	    for ( i = 0; i < num_errs; i++ )
+		{
+		SPF_error_t *err;
+		err = SPF_response_message( ld->responsep, i );
+		if ( err )
+		    {
+		    if ( SPF_error_code( err ) == SPF_E_DNSSEC_FAILURE )
+			{
+			if ( debug )
+			    printf( "spfmilter: DNSSEC validation failure occured.  Rejecting mail.\n" );
+			retval = SPFMILTER_RESULT_FAIL;
+			break;
+			}
+		    }
+		}
+	    }
+#endif
+
+        return retval;
+}
+
+static const char* lib_get_reason( lib_data_t* ld )
+{
+    int spf_reason = SPF_response_reason (ld->responsep);
+    return SPF_strreason (spf_reason);
+}
+
+static const char* lib_get_explanation( lib_data_t* ld )
+{
+    return SPF_response_get_explanation (ld->responsep);
+}
+
+static const char* lib_get_error( lib_data_t* ld )
+{
+    SPF_error_t *err;
+    err = SPF_response_message (ld->responsep, 0);
+    if (err)
+	{
+	return SPF_error_message(err);
+	}
+    else
+	{
+	return NULL;
+	}
+}
+
+static const char* lib_get_error_msg( lib_data_t* ld )
+{
+    return lib_get_error(ld);
+}
+
+static const size_t lib_get_num_errors( lib_data_t* ld )
+{
+    return SPF_response_warnings(ld->responsep);
+}
+
+static const char** lib_get_error_msgs( lib_data_t* ld )
+{
+    int i;
+    int num_errs;
+    char ** err_msgs;
+    
+    num_errs = lib_get_num_errors(ld);
+    err_msgs = (char **) malloc(num_errs * sizeof(char*));
+
+    if (err_msgs == NULL)
+	{
+	return NULL;
+	}
+
+    for (i = 0; i < num_errs; i++)
+	{
+	SPF_error_t *err;
+	char *errmsg = NULL;
+	
+	err = SPF_response_message(ld->responsep, i);
+	if (err)
+	    {
+	    errmsg = (char *)(SPF_error_message (err));
+	    }
+	err_msgs[i] = errmsg;
+	}
+
+    if (ld->err_msgs) free(ld->err_msgs);
+    ld->err_msgs = err_msgs;
+
+    return (const char **) err_msgs;
+}
+
+static void lib_fini_message_data( lib_data_t* ld )
+{
+    free(ld->from);
+}
+
+static void lib_fini_connection_data( lib_data_t* ld )
+{
+    if (ld->err_msgs) free(ld->err_msgs);
+    SPF_response_free (ld->responsep);
+    SPF_request_free (ld->requestp);
+    SPF_server_free(ld->spf_server);
+}
+
+static void lib_fini_fallback( lib_fallback_t* lf )
+{
+    SPF_response_free (lf->responsep);
+    SPF_request_free (lf->requestp);
+    free(lf);
+}
+
+static void lib_fini( void )
+{
+    SPF_server_free(spf_server);
+}
+
+#endif /* USE_LIBSPF2_1_2_X */