Package: libspf2-2
Version: 1.2.10-5
Tags: patch

Dear Maintainer,

the library does not provide any data for the Received-SPF header or the
explanation when:
a) the domain does not publish any SPF records or
b) the domain publishes more than one SPF record (which is a permerror)

This is annoying when using the library within exim, because you have to
build up the header data yourself if you want to add one. There is an
exim bug for that: https://bugs.exim.org/show_bug.cgi?id=1399

But it is indeed a library issue. I've attached a patch to fix it.

Note that the move of case SPF_RESULT_NONE in spf_interpret.c has
already been applied in upstreams master branch:
https://github.com/shevek/libspf2/commit/fc02a07a07f3718a687f04134c6d56460e41e793

For the remaining part of my patch I've just filed a pull request to
upstream: https://github.com/shevek/libspf2/pull/9

As upstream does not make releases so often (the current one is more
than 2 years old!), I'd appreciate if the Debian package applies it.

Here an illustration of the difference using the spfquery tool to access
the library.
Without my patch (version 1.2.10-5):
> $ spfquery -ip 1.2.3.4 -sender '[email protected]'
> StartError
> Context: Failed to query MAIL-FROM
> ErrorCode: (2) Could not find a valid SPF record
> Error: No DNS data for 'www.google.de'.
> EndError
> none
>
>
>
> $ spfquery -ip 1.2.3.4 -sender '[email protected]'
> StartError
> Context: Failed to query MAIL-FROM
> ErrorCode: (32) Multiple SPF or TXT records for domain.
> Error: Multiple SPF records for 'neos.io'
> EndError
> permerror
>
>
>

With my patch (applied to version 1.2.10-5):
> $ spfquery -ip 1.2.3.4 -sender '[email protected]'
> StartError
> Context: Failed to query MAIL-FROM
> ErrorCode: (2) Could not find a valid SPF record
> Error: No DNS data for 'www.google.de'.
> EndError
> none
>
> spfquery: domain of www.google.de does not provide an SPF record
> Received-SPF: none (spfquery: domain of www.google.de does not
> provide an SPF record) client-ip=1.2.3.4; envelope-
> [email protected];
> $ spfquery -ip 1.2.3.4 -sender '[email protected]'
> StartError
> Context: Failed to query MAIL-FROM
> ErrorCode: (32) Multiple SPF or TXT records for domain.
> Error: Multiple SPF records for 'neos.io'
> EndError
> permerror
>
> spfquery: error in processing during lookup of domain of neos.io:
> Multiple SPF or TXT records for domain.
> Received-SPF: permerror (spfquery: error in processing during lookup
> of domain of neos.io: Multiple SPF or TXT records for domain.) client-
> ip=1.2.3.4; [email protected];

(At the time of writing this bug, neos.io had two records in DNS:
neos.io. TXT "v=spf1 include:mail.zendesk.com ?all"
neos.io. TXT "v=spf1 include:mailgun.org ~all" )

--
Sebastian
diff --git a/src/libspf2/spf_interpret.c b/src/libspf2/spf_interpret.c
index a35b58c..5f15df4 100644
--- a/src/libspf2/spf_interpret.c
+++ b/src/libspf2/spf_interpret.c
@@ -104,7 +104,6 @@ SPF_i_set_smtp_comment(SPF_response_t *spf_response)
 		case SPF_RESULT_FAIL:
 		case SPF_RESULT_SOFTFAIL:
 		case SPF_RESULT_NEUTRAL:
-		case SPF_RESULT_NONE:
 
 			err = SPF_i_set_explanation(spf_response);
 			if (err != SPF_E_SUCCESS)
@@ -126,6 +125,7 @@ SPF_i_set_smtp_comment(SPF_response_t *spf_response)
 		case SPF_RESULT_PASS:
 		case SPF_RESULT_TEMPERROR:
 		case SPF_RESULT_PERMERROR:
+		case SPF_RESULT_NONE:
 		default:
 			break;
 	}
@@ -380,7 +380,7 @@ SPF_i_set_received_spf(SPF_response_t *spf_response)
  * This must be called with EITHER
  * spf_response->spf_record_exp != NULL
  *   OR
- * result in { SPF_RESULT_PASS SPF_RESULT_INVALID
+ * result in { SPF_RESULT_NONE SPF_RESULT_PASS SPF_RESULT_INVALID
  *		SPF_RESULT_TEMPERROR SPF_RESULT_PERMERROR }
  * or the library will abort when it tries to generate an explanation.
  */
diff --git a/src/libspf2/spf_server.c b/src/libspf2/spf_server.c
index d648b4e..66beb69 100644
--- a/src/libspf2/spf_server.c
+++ b/src/libspf2/spf_server.c
@@ -361,8 +361,9 @@ retry:
 			}
 			spf_response->result = SPF_RESULT_NONE;
 			spf_response->reason = SPF_REASON_FAILURE;
-			return SPF_response_add_error(spf_response, SPF_E_NOT_SPF,
-					"Host '%s' not found.", domain);
+			return SPF_i_done(spf_response, SPF_RESULT_NONE, SPF_REASON_FAILURE,
+					SPF_response_add_error(spf_response, SPF_E_NOT_SPF,
+						"Host '%s' not found.", domain));
 			// break;
 
 		case NO_DATA:
@@ -375,8 +376,9 @@ retry:
 			}
 			spf_response->result = SPF_RESULT_NONE;
 			spf_response->reason = SPF_REASON_FAILURE;
-			return SPF_response_add_error(spf_response, SPF_E_NOT_SPF,
-					"No DNS data for '%s'.", domain);
+			return SPF_i_done(spf_response, SPF_RESULT_NONE, SPF_REASON_FAILURE,
+					SPF_response_add_error(spf_response, SPF_E_NOT_SPF,
+						"No DNS data for '%s'.", domain));
 			// break;
 
 		case TRY_AGAIN:
@@ -453,17 +455,18 @@ retry:
 		}
 		spf_response->result = SPF_RESULT_NONE;
 		spf_response->reason = SPF_REASON_FAILURE;
-		return SPF_response_add_error(spf_response, SPF_E_NOT_SPF,
-				"No SPF records for '%s'", domain);
+		return SPF_i_done(spf_response, SPF_RESULT_NONE, SPF_REASON_FAILURE,
+				SPF_response_add_error(spf_response, SPF_E_NOT_SPF,
+					"No SPF records for '%s'", domain));
 	}
 	if (num_found > 1) {
 		SPF_dns_rr_free(rr_txt);
 		// rfc4408 requires permerror here.
-		/* XXX This could be refactored with SPF_i_done. */
 		spf_response->result = SPF_RESULT_PERMERROR;
 		spf_response->reason = SPF_REASON_FAILURE;
-		return SPF_response_add_error(spf_response, SPF_E_MULTIPLE_RECORDS,
-				"Multiple SPF records for '%s'", domain);
+		return SPF_i_done(spf_response, SPF_RESULT_PERMERROR, SPF_REASON_FAILURE,
+				SPF_response_add_error(spf_response, SPF_E_MULTIPLE_RECORDS,
+					"Multiple SPF records for '%s'", domain));
 	}
 
 	/* try to compile the SPF record */

Reply via email to