diff -Naur postfix-2.7.1.orig/README_FILES/SPF_README postfix-2.7.1/README_FILES/SPF_README
--- postfix-2.7.1.orig/README_FILES/SPF_README	1970-01-01 01:00:00.000000000 +0100
+++ postfix-2.7.1/README_FILES/SPF_README	2010-10-05 19:20:26.824361237 +0200
@@ -0,0 +1,173 @@
+Postfix SPF support
+
+-------------------------------------------------------------------------------
+
+SPF patch for libspf2 >= 1.2.0 by Nigel Kukard, partly based on work
+by Dean Strik's and Jef Poskanzer's spfmilter.
+
+Fixes and enhancements by Martin Matuska <mm@FreeBSD.org>
+
+Patch site:       http://www.vx.sk/postfix-spf/
+License:          Secure Mailer License (Postfix License)
+
+
+ChangeLog
+
+22.09.2010, Martin Matuska <mm@FreeBSD.org>
+- updated for Postfix 2.7.1
+- fixed IPv6 support
+
+01.10.2010, Martin Matuska <mm@FreeBSD.org>
+- added permit_spf_valid_sender
+- changed build to use -DHAS_SPF
+
+02.10.2010, Martin Matuska <mm@FreeBSD.org>
+- fixed SPF patch version output
+- updated SPF_README
+
+05.10.2010, Martin Matuska <mm@FreeBSD.org>
+- fixed spf_explanation, spf_local_policy and spf_global_whitelist
+
+
+About this document
+
+This document describes how to configure Postfix to use SPF ("Sender
+Policy Framework") validation. It does not describe the function or
+design of SPF itself. Refer to one or more of the websites listed at
+the end of this text for more information.
+
+The actual SPF validation is offloaded to a special library called
+libspf2. It is therefore necessary that you install libspf2 on your
+system. You can find libspf2 either in your usual package repository or
+at http://www.libspf2.org/.
+
+
+Building Postfix with SPF support
+
+To build Postfix with SPF support, first we need to generate the make(1) files
+with the necessary definitions. This is done by invoking the command "make
+makefiles" in the Postfix top-level directory and with arguments as shown next.
+
+  * If the libspf2 include files are in directory /usr/include/spf2
+    and the libspf2 library (e.g libspf2.so) are in directory /usr/lib:
+
+    % make tidy # if you have left-over files from a previous build
+    % make makefiles CCARGS="-DHAS_SPF -DHAVE_NS_TYPE" AUXLIBS="-lspf2"
+    % make
+
+  * If the libspf2 include files are in directory /usr/local/include/spf2
+    and the libspf2 library (e.g libspf2.so) are in directory /usr/local/lib:
+
+    % make tidy # if you have left-over files from a previous build
+    % make makefiles CCARGS="-I/usr/local/include -DHAS_SPF -DHAVE_NS_TYPE" \
+	AUXLIBS="-L/usr/local/lib -lspf2"
+    % make
+
+If you need to apply other customizations (such as Berkeley DB databases,
+MySQL, PostgreSQL, LDAP or SASL), see the respective Postfix README documents,
+and combine their "make makefiles" instructions with the instructions above:
+
+    % make tidy # if you have left-over files from a previous build
+    % make makefiles CCARGS="-DHAS_SPF -DHAVE_NS_TYPE \
+        (other -D or -I options)" \
+        AUXLIBS="-lspf2 \
+        (other -l options for libraries in /usr/lib) \
+        (-L/path/name + -l options for other libraries)"
+
+The -DHAVE_NS_TYPE flag in all examples above is only needed if your system
+complains about ns_type conflicting. To complete the build process, see the 
+Postfix INSTALL instructions.
+
+
+SPF sender restrictions
+
+Postfix SPF support introduces two additional sender restrictions:
+
+reject_spf_invalid_sender
+	Reject the request when the sender credentials are evaluated
+	by SPF as invalid.
+
+permit_spf_valid_sender
+	Permit the request when the sender credentials are evaluated
+	by SPF as valid.
+
+Example:
+    /etc/postfix/main.cf:
+        smtpd_sender_restrictions =
+            ...
+            reject_spf_invalid_sender
+            ...
+
+
+SPF received header
+
+Postfix will by default add a mail header, Received-SPF:, to any mail
+passing the SPF validation. This information can be useful for the
+recipient of the message. You can disable this behaviour by setting
+'spf_received_header = no'.
+
+    /etc/postfix/main.cf:
+        spf_received_header = no
+
+
+Action on SPF reject
+
+By default, if using the sender restriction "reject_spf_invalid_sender",
+Postfix will reject mail with invalid sender credentials.
+You can however choose to prevent this from happening, and let the mail
+pass, by setting 'spf_mark_only = yes'. The Received-SPF: header
+(if enabled, see above) will show that the mail failed the test.
+
+    /etc/postfix/main.cf:
+        spf_mark_only = yes
+
+
+SPF reject code
+
+You can set the numerical SMTP response code when rejecting mails
+due to SPF rule violations by changing the value of the
+'spf_reject_code' variable (default: 550).
+
+    /etc/postfix/main.cf:
+        spf_reject_code = 550
+
+
+SPF explanation string
+
+If a site does provide SPF DNS records yet no explanation, a generic
+explanation will be used, with a URL to visit for more information.
+You can override this generic explanation by setting the "spf_explanation"
+configuration option. See the SPF reference sites for information about 
+the format used.
+
+    /etc/postfix/main.cf:
+	spf_explanation = "%{h} [%{i}] is not allowed to send mail for %{s}"
+
+
+SPF global whitelist
+
+There exists a global SPF whitelist on trusted-forwarder.org. You can
+enable use of this global whitelist by setting the variable
+'spf_global_whitelist = yes'.
+
+    /etc/postfix/main.cf:
+	spf_global_whitelist = yes
+
+
+SPF local policy
+
+It is also possible to set a local policy using the spf_local_policy
+setting. Currently the format is not documented here.
+
+-------------------------------------------------------------------------------
+
+Downloads and information with regard to this patch can be found at 
+http://www.vx.sk/postfix-spf/
+
+Links:
+	http://www.linuxrulz.org/nkukard/postfix/	- Updates by Kukard
+	http://www.ipnet6.org/postfix/spf/		- Original patch home
+	http://spf.pobox.com/				- SPF background
+	http://www.libspf2.org/				- LibSPF2 site
+	http://www.trusted-forwarder.org/		- Global whitelist
+	http://www.postfix.org/				- Postfix home page
diff -Naur postfix-2.7.1.orig/conf/postfix-files postfix-2.7.1/conf/postfix-files
--- postfix-2.7.1.orig/conf/postfix-files	2010-09-22 23:23:58.000000000 +0200
+++ postfix-2.7.1/conf/postfix-files	2010-09-22 23:25:18.000000000 +0200
@@ -274,6 +274,7 @@
 $readme_directory/SMTPD_ACCESS_README:f:root:-:644
 $readme_directory/SMTPD_POLICY_README:f:root:-:644
 $readme_directory/SMTPD_PROXY_README:f:root:-:644
+$readme_directory/SPF_README:f:root:-:644
 $readme_directory/STANDARD_CONFIGURATION_README:f:root:-:644
 $readme_directory/STRESS_README:f:root:-:644
 $readme_directory/TLS_LEGACY_README:f:root:-:644
diff -Naur postfix-2.7.1.orig/src/global/mail_params.c postfix-2.7.1/src/global/mail_params.c
--- postfix-2.7.1.orig/src/global/mail_params.c	2010-10-05 19:17:09.861572213 +0200
+++ postfix-2.7.1/src/global/mail_params.c	2010-10-05 19:17:34.892314496 +0200
@@ -303,6 +303,10 @@
 char   *var_multi_name;
 bool    var_multi_enable;
 
+#ifdef HAS_SPF
+char   *var_spf_pversion;
+#endif
+
 const char null_format_string[1] = "";
 
 /* check_myhostname - lookup hostname and validate */
@@ -569,6 +573,9 @@
 	VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0,
 	/* multi_instance_wrapper may have dependencies but not dependents. */
 	VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0,
+#ifdef HAS_SPF
+	VAR_SPF_PVERSION, DEF_SPF_PVERSION, &var_spf_pversion, 1, 0,
+#endif
 	0,
     };
     static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
diff -Naur postfix-2.7.1.orig/src/global/mail_params.h postfix-2.7.1/src/global/mail_params.h
--- postfix-2.7.1.orig/src/global/mail_params.h	2010-10-05 19:17:09.850525904 +0200
+++ postfix-2.7.1/src/global/mail_params.h	2010-10-05 19:17:34.898340085 +0200
@@ -2777,6 +2777,40 @@
 #define CHECK_POLICY_SERVICE		"check_policy_service"
 
  /*
+  * SPF support.
+  */
+#define PERMIT_SPF_VALID_SENDER		"permit_spf_valid_sender"
+#define REJECT_SPF_INVALID_SENDER	"reject_spf_invalid_sender"
+
+#define VAR_SPF_REJECT_CODE		"spf_reject_code"
+#define DEF_SPF_REJECT_CODE		550
+extern int var_spf_reject_code;
+
+#define VAR_SPF_REJECT_DSN              "spf_reject_dsn"
+#define DEF_SPF_REJECT_DSN              "5.7.1"
+extern char *var_spf_reject_dsn;
+
+#define VAR_SPF_MARK_ONLY		"spf_mark_only"
+#define DEF_SPF_MARK_ONLY		0
+extern bool var_spf_mark_only;
+
+#define VAR_SPF_RCVD_HEADER		"spf_received_header"
+#define DEF_SPF_RCVD_HEADER		1
+extern bool var_spf_rcvd_header;
+
+#define VAR_SPF_LOCAL_POLICY		"spf_local_policy"
+#define DEF_SPF_LOCAL_POLICY		""
+extern char *var_spf_local_policy;
+
+#define VAR_SPF_EXPLANATION		"spf_explanation"
+#define DEF_SPF_EXPLANATION		""
+extern char *var_spf_explanation;
+
+#define VAR_SPF_GLOBAL_WHITELIST	"spf_global_whitelist"
+#define DEF_SPF_GLOBAL_WHITELIST	0
+extern bool var_spf_global_whitelist;
+
+ /*
   * Client rate control.
   */
 #define VAR_SMTPD_CRATE_LIMIT		"smtpd_client_connection_rate_limit"
diff -Naur postfix-2.7.1.orig/src/global/mail_version.h postfix-2.7.1/src/global/mail_version.h
--- postfix-2.7.1.orig/src/global/mail_version.h	2010-10-05 19:17:09.845506861 +0200
+++ postfix-2.7.1/src/global/mail_version.h	2010-10-05 19:17:34.899342441 +0200
@@ -67,6 +67,15 @@
 #define MAIL_VERSION_STAMP_ALLOCATE \
     mail_version_stamp = strdup(VAR_MAIL_VERSION "=" DEF_MAIL_VERSION)
 
+#ifdef HAS_SPF
+/*
+ * SPF patch version.
+ */
+#define VAR_SPF_PVERSION	"spf_patch_version"
+#define DEF_SPF_PVERSION	"1.1.0"
+extern char *var_spf_pversion;
+#endif
+
 /* LICENSE
 /* .ad
 /* .fi
diff -Naur postfix-2.7.1.orig/src/smtpd/Makefile.in postfix-2.7.1/src/smtpd/Makefile.in
--- postfix-2.7.1.orig/src/smtpd/Makefile.in	2010-10-05 19:17:09.813378952 +0200
+++ postfix-2.7.1/src/smtpd/Makefile.in	2010-10-05 19:17:34.900353737 +0200
@@ -18,6 +18,10 @@
 	../../lib/libxsasl.a ../../lib/libmilter.a ../../lib/libglobal.a \
 	../../lib/libutil.a
 
+SRCS	+= smtpd_spf.c
+OBJS	+= smtpd_spf.o
+HDRS	+= smtpd_spf.h
+
 .c.o:;	$(CC) $(CFLAGS) -c $*.c
 
 $(PROG): $(OBJS) $(LIBS)
diff -Naur postfix-2.7.1.orig/src/smtpd/smtpd.c postfix-2.7.1/src/smtpd/smtpd.c
--- postfix-2.7.1.orig/src/smtpd/smtpd.c	2010-10-05 19:17:09.812377155 +0200
+++ postfix-2.7.1/src/smtpd/smtpd.c	2010-10-05 19:17:34.908392139 +0200
@@ -1060,6 +1060,10 @@
 #include <smtpd_proxy.h>
 #include <smtpd_milter.h>
 
+#ifdef HAS_SPF
+#include <smtpd_spf.h>
+#endif
+
  /*
   * Tunable parameters. Make sure that there is some bound on the length of
   * an SMTP command, so that the mail system stays in control even when a
@@ -1168,6 +1172,17 @@
 char   *var_smtpd_ehlo_dis_words;
 char   *var_smtpd_ehlo_dis_maps;
 
+#ifdef HAS_SPF
+bool    var_spf_mark_only;
+int     var_spf_reject_code;
+char   *var_spf_reject_dsn;
+bool    var_spf_rcvd_header;
+
+char   *var_spf_local_policy;
+char   *var_spf_explanation;
+bool    var_spf_global_whitelist;
+#endif
+
 char   *var_smtpd_tls_level;
 bool    var_smtpd_use_tls;
 bool    var_smtpd_enforce_tls;
@@ -2326,6 +2341,9 @@
 #ifdef DELAY_ACTION
     state->saved_delay = 0;
 #endif
+#ifdef HAS_SPF
+    smtpd_spf_sess_reset(state);
+#endif
 #ifdef USE_SASL_AUTH
     if (smtpd_sasl_is_active(state))
 	smtpd_sasl_mail_reset(state);
@@ -2801,6 +2819,16 @@
 	for (cpp = state->prepend->argv; *cpp; cpp++)
 	    out_fprintf(out_stream, REC_TYPE_NORM, "%s", *cpp);
 
+#ifdef HAS_SPF
+    /*
+     * Prepend Received-SPF header. The header (name,value) has been
+     * constructed before in the SPF handler (if SPF is enabled).
+     */
+    if (var_spf_rcvd_header && state->spf_sess_data != NULL
+	    && state->spf_header)
+	out_fprintf(out_stream, REC_TYPE_NORM, "%s", state->spf_header);
+#endif
+
     /*
      * Suppress our own Received: header in the unlikely case that we are an
      * intermediate proxy.
@@ -4983,6 +5011,9 @@
 	VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0,
 	VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0,
 #endif
+#ifdef HAS_SPF
+	VAR_SPF_REJECT_CODE, DEF_SPF_REJECT_CODE, &var_spf_reject_code, 0, 0,
+#endif
 	0,
     };
     static const CONFIG_TIME_TABLE time_table[] = {
@@ -5027,6 +5058,11 @@
 	VAR_SMTPD_PEERNAME_LOOKUP, DEF_SMTPD_PEERNAME_LOOKUP, &var_smtpd_peername_lookup,
 	VAR_SMTPD_DELAY_OPEN, DEF_SMTPD_DELAY_OPEN, &var_smtpd_delay_open,
 	VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, &var_smtpd_client_port_log,
+#ifdef HAS_SPF
+	VAR_SPF_MARK_ONLY, DEF_SPF_MARK_ONLY, &var_spf_mark_only,
+	VAR_SPF_RCVD_HEADER, DEF_SPF_RCVD_HEADER, &var_spf_rcvd_header,
+	VAR_SPF_GLOBAL_WHITELIST, DEF_SPF_GLOBAL_WHITELIST, &var_spf_global_whitelist,
+#endif
 	0,
     };
     static const CONFIG_STR_TABLE str_table[] = {
@@ -5119,6 +5155,11 @@
 	VAR_UNV_RCPT_TF_ACT, DEF_UNV_RCPT_TF_ACT, &var_unv_rcpt_tf_act, 1, 0,
 	VAR_UNV_FROM_TF_ACT, DEF_UNV_FROM_TF_ACT, &var_unv_from_tf_act, 1, 0,
 	VAR_SMTPD_CMD_FILTER, DEF_SMTPD_CMD_FILTER, &var_smtpd_cmd_filter, 0, 0,
+#ifdef HAS_SPF
+	VAR_SPF_LOCAL_POLICY, DEF_SPF_LOCAL_POLICY, &var_spf_local_policy, 0, 0,
+	VAR_SPF_EXPLANATION, DEF_SPF_EXPLANATION, &var_spf_explanation, 0, 0,
+	VAR_SPF_REJECT_DSN, DEF_SPF_REJECT_DSN, &var_spf_reject_dsn, 0, 0,
+#endif
 	0,
     };
     static const CONFIG_RAW_TABLE raw_table[] = {
diff -Naur postfix-2.7.1.orig/src/smtpd/smtpd.h postfix-2.7.1/src/smtpd/smtpd.h
--- postfix-2.7.1.orig/src/smtpd/smtpd.h	2010-10-05 19:17:09.809363103 +0200
+++ postfix-2.7.1/src/smtpd/smtpd.h	2010-10-05 19:17:34.909383600 +0200
@@ -14,6 +14,13 @@
 #include <sys/time.h>
 #include <unistd.h>
 
+#ifdef HAS_SPF
+#include <arpa/nameser.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <spf2/spf.h>
+#endif
+
  /*
   * Utility library.
   */
@@ -150,6 +157,14 @@
     VSTRING *dsn_buf;			/* scratch space for xtext expansion */
     VSTRING *dsn_orcpt_buf;		/* scratch space for ORCPT parsing */
 
+#ifdef HAS_SPF
+    /*
+     * SPF.
+     */
+    SPF_request_t *spf_sess_data;	/* session specific SPF data */
+    char *spf_header;			/* SPF header to insert */
+#endif
+
     /*
      * Pass-through proxy client.
      */
diff -Naur postfix-2.7.1.orig/src/smtpd/smtpd_check.c postfix-2.7.1/src/smtpd/smtpd_check.c
--- postfix-2.7.1.orig/src/smtpd/smtpd_check.c	2010-10-05 19:17:09.810367415 +0200
+++ postfix-2.7.1/src/smtpd/smtpd_check.c	2010-10-05 19:17:34.918417654 +0200
@@ -246,6 +246,10 @@
 #include "smtpd_dsn_fix.h"
 #include "smtpd_resolve.h"
 
+#ifdef HAS_SPF
+#include "smtpd_spf.h"
+#endif
+
 #define RESTRICTION_SEPARATORS ", \t\r\n"
 
  /*
@@ -1740,6 +1744,107 @@
     return (stat);
 }
 
+#ifdef HAS_SPF
+/* permit_spf_valid_sender - permit valid sender using SPF records */
+
+static int permit_spf_valid_sender(SMTPD_STATE *state, const char *addr,
+			    const char *reply_name, const char *reply_class)
+{
+    char   *myname = "permit_spf_valid_sender";
+    char   *comment;
+    int     action, stat;
+
+    /*
+     * Initialize SPF data
+     */
+    smtpd_spf_sess_init(state);
+    smtpd_spf_set_helo(state, state->helo_name);
+    smtpd_spf_set_from(state, state->sender);
+
+    /*
+     * Obtain SPF result.
+     */
+    comment = NULL;
+    action = smtpd_spf_result(state,
+		(var_spf_rcvd_header ? &state->spf_header : NULL),
+		&comment);
+
+    /*
+     * Perform actions.
+     */
+    if (action == SPF_ACTION_ACCEPT)
+	return (SMTPD_CHECK_OK);
+    else return (SMTPD_CHECK_DUNNO);
+
+    /*
+     * Cleanup.
+     */
+    if (comment != NULL)
+        myfree(comment);
+
+    return (stat);
+}
+
+
+/* reject_spf_invalid_sender - check sender validity using SPF records */
+
+static int reject_spf_invalid_sender(SMTPD_STATE *state, const char *addr,
+			    const char *reply_name, const char *reply_class)
+{
+    char   *myname = "reject_spf_invalid_sender";
+    char   *comment;
+    int     action, stat;
+
+    /*
+     * Initialize SPF data
+     */
+    smtpd_spf_sess_init(state);
+    smtpd_spf_set_helo(state, state->helo_name);
+    smtpd_spf_set_from(state, state->sender);
+
+    /*
+     * Obtain SPF result.
+     */
+    comment = NULL;
+    action = smtpd_spf_result(state,
+		(var_spf_rcvd_header ? &state->spf_header : NULL),
+		&comment);
+
+    /*
+     * Perform actions.
+     */
+    stat = SMTPD_CHECK_DUNNO;
+    switch (action) {
+	case SPF_ACTION_REJECT:
+	    stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
+		    var_spf_reject_code, var_spf_reject_dsn,
+		    "<%s>: %s rejected: %s",
+		    reply_name, reply_class,
+		    (comment ? comment : "SPF policy violation"));
+	    break;
+
+	case SPF_ACTION_TEMPFAIL:
+	    /* XXX log error? */
+	   DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
+		   450, "4.7.1",
+		   "<%s>: %s rejected: Unable to look up SPF information",
+		   reply_name, reply_class);
+	   break;
+
+	default:
+	   break;
+    }
+
+    /*
+     * Cleanup.
+     */
+    if (comment != NULL)
+        myfree(comment);
+
+    return (stat);
+}
+#endif
+
 /* reject_unknown_address - fail if address does not resolve */
 
 static int reject_unknown_address(SMTPD_STATE *state, const char *addr,
@@ -3826,6 +3931,22 @@
 	    if (state->sender && *state->sender)
 		status = reject_non_fqdn_address(state, state->sender,
 					  state->sender, SMTPD_NAME_SENDER);
+	} else if (strcasecmp(name, PERMIT_SPF_VALID_SENDER) == 0) {
+#ifdef HAS_SPF
+	    if (state->sender && *state->sender)
+		status = permit_spf_valid_sender(state, state->sender,
+					  state->sender, SMTPD_NAME_SENDER);
+#else
+	    msg_warn("restriction `%s' ignored: no SPF support", name);
+#endif
+	} else if (strcasecmp(name, REJECT_SPF_INVALID_SENDER) == 0) {
+#ifdef HAS_SPF
+	    if (state->sender && *state->sender)
+		status = reject_spf_invalid_sender(state, state->sender,
+					  state->sender, SMTPD_NAME_SENDER);
+#else
+	    msg_warn("restriction `%s' ignored: no SPF support", name);
+#endif
 	} else if (strcasecmp(name, REJECT_AUTH_SENDER_LOGIN_MISMATCH) == 0) {
 #ifdef USE_SASL_AUTH
 	    if (var_smtpd_sasl_enable) {
diff -Naur postfix-2.7.1.orig/src/smtpd/smtpd_spf.c postfix-2.7.1/src/smtpd/smtpd_spf.c
--- postfix-2.7.1.orig/src/smtpd/smtpd_spf.c	1970-01-01 01:00:00.000000000 +0100
+++ postfix-2.7.1/src/smtpd/smtpd_spf.c	2010-10-05 19:18:09.387805660 +0200
@@ -0,0 +1,347 @@
+/*++
+/* NAME
+/*	smtpd_spf 3
+/* SUMMARY
+/*	SMTP server SPF support
+/* SYNOPSIS
+/*	#include <smtpd.h>
+/*	#include <smtpd_spf.h>
+/*
+/*	void	smtpd_spf_init(state)
+/*	SMTPD_STATE *state;
+/*
+/*	int	smtpd_spf_sess_init(state)
+/*	SMTPD_STATE *state;
+/*
+/*	void	smtpd_spf_sess_reset(state)
+/*	SMTPD_STATE *state;
+/*
+/*	int	smtpd_spf_set_helo(state, name)
+/*	SMTPD_STATE *state;
+/*	char	*name;
+/*
+/*	int	smtpd_spf_set_from(state, name)
+/*	SMTPD_STATE *state;
+/*	char	*name;
+/*
+/*	int	smtpd_spf_result(state, *header, *comment)
+/*	SMTPD_STATE *state;
+/*	char	**header;
+/*	char	**comment;
+/*
+/* DESCRIPTION
+/*	This modules provides SPF state management functions,
+/*	making the other SMTP components independent on the
+/*	actual SPF routines used.
+/*
+/*	smtpd_spf_init() initializes global SPF context.
+/*
+/*	smtpd_spf_sess_init() initializes SPF session context.
+/*
+/*	smtpd_spf_sess_reset() cleans up SPF session context.
+/*
+/*	smtpd_spf_set_helo() passes the client HELO name to
+/*	the underlying libspf2 context.
+/*
+/*	smtpd_spf_set_from() passes the SMTP envelope sender
+/*	to the underlying libspf2 context.
+/*
+/*	smtpd_spf_result() performs (via libspf2) the SPF lookups
+/*	and handling, and creates a Received-SPF header.
+/*
+/*	Arguments:
+/* .IP state
+/*	Session context.
+/* .IP name
+/*	The value to set in the low-level SPF context.
+/* DIAGNOSTICS
+/*	Panic: interface violations. Fatal errors: out of memory.
+/*	internal protocol errors.
+/* LICENSE
+/* .ad
+/* .fi
+/*	The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* 	Nigel Kukard
+/* 	E-mail: <nkukard@lbsd.net>
+/*
+/*      Dean C. Strik
+/*      Department ICT
+/*      Eindhoven University of Technology
+/*      P.O. Box 513
+/*      5600 MB  Eindhoven, Netherlands
+/*      E-mail: <dean@ipnet6.org>
+/*--*/
+
+#ifdef HAS_SPF
+/* System library. */
+#include <sys_defs.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <spf2/spf.h>
+#include <spf2/spf_dns_resolv.h>
+#include <spf2/spf_dns_cache.h>
+
+/* Global library */
+#include <mail_params.h>
+#include <msg.h>
+#include <mymalloc.h>
+
+/* Application library */
+#include "smtpd.h"
+#include "smtpd_spf.h"
+
+#define SPF_DNS_CACHE_BITS 8
+
+//static SPF_config_t	spf_global_data;	/* common SPF configuration data */
+//static SPF_dns_config_t	spf_resolv_data;	/* SPF DNS resolver data */
+//static SPF_dns_config_t	spf_resolv_cache;	/* SPF DNS resolver cache */
+//static SPF_c_results_t	spf_local_policy;	/* compiled local policy */
+//static SPF_c_results_t	spf_explanation;	/* custom explanation */
+
+static SPF_server_t	*spf_global_server;
+
+
+/* Initialize global SPF context */
+void smtpd_spf_init(SMTPD_STATE *state)
+{
+	char   *myname = "smtpd_spf_global_init";
+	SPF_response_t *spf_response;
+	int res;
+
+
+	/*
+	* Initialize libspf2 server
+	*/
+	spf_global_server = SPF_server_new(SPF_DNS_CACHE, 0);
+	if (spf_global_server == NULL)
+		msg_fatal("%s: unable to create SPF server", myname);
+
+	if (SPF_server_set_rec_dom(spf_global_server, var_myhostname) != 0)
+		msg_fatal("%s: can't set SPF hostname", myname);
+
+	if (var_spf_explanation != NULL && *var_spf_explanation != 0)
+	{
+		spf_response = NULL;
+		res = SPF_server_set_explanation(spf_global_server, var_spf_explanation, 
+				&spf_response);
+		if (spf_response)
+		    SPF_response_free(spf_response);
+		if (res != SPF_E_SUCCESS)
+		{
+			msg_fatal("%s: can't set SPF explanation (SPF error code: %d)", myname, res);
+		}
+	}
+
+	if ((var_spf_local_policy != NULL && *var_spf_local_policy != 0) ||
+	    (var_spf_global_whitelist))
+	{
+		spf_response = NULL;
+		res = SPF_server_set_localpolicy(spf_global_server,
+				var_spf_local_policy ? var_spf_local_policy : "",
+				var_spf_global_whitelist,
+				&spf_response);
+		if (spf_response)
+		    SPF_response_free(spf_response);
+		if (res != SPF_E_SUCCESS)
+		{
+			msg_fatal("%s: can't set SPF local policy (SPF error code: %d)", myname, res);
+		}
+	}
+
+	/*
+	* Clear session-specific data (session init is on-demand)
+	*/
+	state->spf_sess_data = NULL;
+	state->spf_header = NULL;
+}
+
+
+/* Initialize session dependent SPF context */
+int smtpd_spf_sess_init(SMTPD_STATE *state)
+{
+	char   *myname = "smtpd_spf_init_sess_data";
+
+
+	/*
+	 * Sanity checks.
+	 */
+	if (state->addr == 0)
+		msg_panic("%s: client address not initialized", myname);
+	if (spf_global_server == NULL)
+		msg_panic("%s: spf_global_server not initialized", myname);
+
+	/*
+	 * This code is recipient-independent. SPF session data is
+	 * already initialized if there have been earlier RCPT TO
+	 * commands in this transaction, and we're done.
+	 * XXX: make the code recipient-dependent (restriction classes)
+	 */
+	if (state->spf_sess_data != NULL)
+		return 0;
+
+	/*
+	 * Initialize session-specific SPF data.
+	 */
+	state->spf_sess_data = SPF_request_new(spf_global_server);
+	if (state->spf_sess_data == NULL)
+		msg_fatal("%s: failed to create SPF session data structure",
+				myname);
+
+	state->spf_header = NULL;
+
+	/*
+	 * Pass client address to libspf2.
+	 */
+#ifdef HAS_IPV6
+	if (state->addr_family == AF_INET6) {
+		if (SPF_request_set_ipv6_str(state->spf_sess_data, state->addr) != 0)
+			msg_fatal("%s: SPF_request_set_ipv6 failure", myname);
+	}
+	else
+#endif
+	if (SPF_request_set_ipv4_str(state->spf_sess_data, state->addr) != 0)
+		msg_fatal("%s: SPF_request_set_ipv4 failure", myname);
+
+	return 0;
+}
+
+
+/* Cleanup after disconnect */
+void smtpd_spf_sess_reset(SMTPD_STATE *state)
+{
+	char   *myname = "smtpd_spf_sess_reset";
+
+	/*
+	 * Sanity checks.
+	 */
+	if (spf_global_server == NULL)
+		msg_panic("%s: no global SPF data initialized", myname);
+
+	if (state->spf_sess_data == NULL)
+		return; /* initialisation is only on demand */
+
+	/*
+	 * Cleanup SPF session data.
+	 */
+	if (state->spf_header != NULL)
+		myfree(state->spf_header);
+
+	state->spf_header = NULL;
+
+	SPF_request_free(state->spf_sess_data);
+
+	state->spf_sess_data = NULL;
+}
+
+
+/* Pass HELO/EHLO name to libspf2 */
+int smtpd_spf_set_helo(SMTPD_STATE *state, const char *name)
+{
+	char   *myname = "smtpd_spf_set_helo";
+
+	/*
+	 * Sanity checks.
+	 *
+	 * 'name' may be NULL, to unset registered HELO. This may
+	 * even happen when SPF is not initialized yet (SPF init
+	 * is only on demand).
+	 */
+	if (state->spf_sess_data == NULL && name == NULL)
+		return 0;
+
+	if (state->spf_sess_data == NULL)
+		msg_panic("%s: setting SPF HELO with null session",
+			myname);
+
+	/*
+	 * Pass the HELO name to libspf2.
+	 */
+	if (SPF_request_set_helo_dom(state->spf_sess_data, name) != 0)
+		msg_fatal("%s: error in SPF_request_set_helo_dom", myname);
+
+
+	return 0;
+}
+
+
+/* Pass sender (env.from) name to libspf2 */
+int smtpd_spf_set_from(SMTPD_STATE *state, const char *name)
+{
+	char *myname = "smtpd_spf_set_from";
+
+	/*
+	 * Pass the envelope sender to libspf2.
+	 */
+	if (SPF_request_set_env_from(state->spf_sess_data, state->sender) != 0)
+		msg_fatal("%s: error in SPF_request_set_env_from", myname);
+
+	return 0;
+}
+
+
+/* Obtain SPF result */
+int smtpd_spf_result(SMTPD_STATE *state, char **headerp, char **commentp)
+{
+	char *myname = "smtpd_spf_result";
+	int action = SPF_ACTION_UNKNOWN;
+	SPF_response_t *spf_response = NULL;
+	int res;
+	char *res_received_spf;
+	char *res_smtp_comment;
+
+	/*
+	 * Obtain SPF result.
+	 */
+	res = SPF_request_query_mailfrom(state->spf_sess_data, &spf_response);
+	if (res != 0)
+		goto clean_end;
+
+	res = SPF_response_result(spf_response);
+	switch (res) {
+		case SPF_RESULT_PASS:
+			action = SPF_ACTION_ACCEPT;
+			break;
+		case SPF_RESULT_SOFTFAIL:
+		case SPF_RESULT_NEUTRAL:
+		case SPF_RESULT_NONE:
+			action = SPF_ACTION_MARK;
+			break;
+
+		case SPF_RESULT_FAIL:
+			action = var_spf_mark_only ? SPF_ACTION_MARK : SPF_ACTION_REJECT;
+			break;
+
+		default:
+			msg_warn("%s: unknown SPF result %d (%s)", myname, res,
+					SPF_strresult(res));
+			action = SPF_ACTION_UNKNOWN;
+			break;
+	}
+
+	/*
+	 * Save the output header/comment.
+	 */
+	res_received_spf = SPF_response_get_received_spf(spf_response);
+	res_smtp_comment = SPF_response_get_smtp_comment(spf_response);
+
+	if (headerp != NULL && res_received_spf != NULL)
+		*headerp = mystrdup(res_received_spf);
+
+	if (commentp != NULL && res_smtp_comment != NULL)
+		*commentp = mystrdup(res_smtp_comment);
+
+	/*
+	 * Cleanup.
+	 */
+clean_end:
+	SPF_response_free(spf_response);
+
+	return (action);
+}
+#endif /* HAS_SPF */
diff -Naur postfix-2.7.1.orig/src/smtpd/smtpd_spf.h postfix-2.7.1/src/smtpd/smtpd_spf.h
--- postfix-2.7.1.orig/src/smtpd/smtpd_spf.h	1970-01-01 01:00:00.000000000 +0100
+++ postfix-2.7.1/src/smtpd/smtpd_spf.h	2010-10-05 19:17:34.919421686 +0200
@@ -0,0 +1,46 @@
+/*++
+/* NAME
+/*	smtpd_spf 3h
+/* SUMMARY
+/*	SMTP server SPF support
+/* SYNOPSIS
+/*	#include <smtpd.h>
+/*	#include <smtpd_spf.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * External interface.
+  */
+#ifdef HAS_SPF
+
+extern void smtpd_spf_init(SMTPD_STATE *);
+extern int smtpd_spf_sess_init(SMTPD_STATE *);
+extern void smtpd_spf_sess_reset(SMTPD_STATE *);
+extern int smtpd_spf_set_helo(SMTPD_STATE *, const char *);
+extern int smtpd_spf_set_from(SMTPD_STATE *, const char *);
+extern int smtpd_spf_result(SMTPD_STATE *, char **, char **);
+
+#define SPF_ACTION_UNKNOWN  0
+#define SPF_ACTION_ACCEPT   1
+#define SPF_ACTION_REJECT   2
+#define SPF_ACTION_MARK     3
+#define SPF_ACTION_TEMPFAIL 4
+
+#endif /* HAS_SPF */
+
+/* LICENSE
+/* .ad
+/* .fi
+/*	The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* 	Nigel Kukard
+/* 	E-mail: <nkukard@lbsd.net>
+/*
+/*      Dean C. Strik
+/*      Department ICT
+/*      Eindhoven University of Technology
+/*      P.O. Box 513
+/*      5600 MB  Eindhoven, Netherlands
+/*      E-mail: <dean@ipnet6.org>
+/*--*/
diff -Naur postfix-2.7.1.orig/src/smtpd/smtpd_state.c postfix-2.7.1/src/smtpd/smtpd_state.c
--- postfix-2.7.1.orig/src/smtpd/smtpd_state.c	2010-10-05 19:17:09.813378952 +0200
+++ postfix-2.7.1/src/smtpd/smtpd_state.c	2010-10-05 19:17:34.920425997 +0200
@@ -67,6 +67,9 @@
 #include "smtpd.h"
 #include "smtpd_chat.h"
 #include "smtpd_sasl_glue.h"
+#ifdef HAS_SPF
+#include "smtpd_spf.h"
+#endif
 
 /* smtpd_state_init - initialize after connection establishment */
 
@@ -158,6 +161,13 @@
      */
     smtpd_peer_init(state);
 
+#ifdef HAS_SPF
+    /*
+     * Initialize SPF connection-specific information.
+     */
+    smtpd_spf_init(state);
+#endif
+
     /*
      * Initialize xforward information.
      */
@@ -191,6 +201,10 @@
 	myfree(state->protocol);
     smtpd_peer_reset(state);
 
+#ifdef HAS_SPF
+    smtpd_spf_sess_reset(state);
+#endif
+
     /*
      * Buffers that are created on the fly and that may be shared among mail
      * deliveries within the same SMTP session.
