Integrated SPF Best Guess. Fixes: bug #521
authorNigel Metheringham <nigel@exim.org>
Tue, 12 Feb 2008 12:52:51 +0000 (12:52 +0000)
committerNigel Metheringham <nigel@exim.org>
Tue, 12 Feb 2008 12:52:51 +0000 (12:52 +0000)
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
doc/doc-txt/experimental-spec.txt
src/src/acl.c
src/src/expand.c
src/src/globals.c
src/src/globals.h
src/src/readconf.c
src/src/spf.c
src/src/spf.h

index 3d939c71879927e913a7c33d398f9fd076e1bb42..6c84133b4ed578089e702f5b4998ef89d3926c56 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.543 2008/02/06 18:57:46 fanf2 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.544 2008/02/12 12:52:51 nm4 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -29,6 +29,10 @@ TF/03 Bugzilla 615: When checking the local_parts router precondition
       does not use the address's named list lookup cache, since this
       contains cached lookups for the whole local part.
 
+NM/05 Bugzilla 521: Integrated SPF Best Guess support contributed by
+      Robert Millan.  Documentation is in experimental-spec.txt
+
+
 
 Exim version 4.69
 -----------------
index e18d215aac21a0df22d56fee9f9c3fc4fbd5af88..1470efc92f381d5b7238c11e990c83e8d6fb8b98 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.157 2007/08/23 11:01:49 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.158 2008/02/12 12:52:51 nm4 Exp $
 
 New Features in Exim
 --------------------
@@ -8,6 +8,13 @@ Before a formal release, there may be quite a lot of detail so that people can
 test from the snapshots or the CVS before the documentation is updated. Once
 the documentation is updated, this file is reduced to a short list.
 
+Version 4.70
+------------
+
+ 1. Preliminary SPF Best Guess support.  Documentation for this is in
+    experimental-spec.txt.
+
+
 Version 4.68
 ------------
 
index 15fd247ae42eb8588ed78b0db26785b4c0f12b96..4175173c320d5cf1113133a8dd7117807a152e54 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/experimental-spec.txt,v 1.10 2008/01/16 09:36:19 tom Exp $
+$Cambridge: exim/doc/doc-txt/experimental-spec.txt,v 1.11 2008/02/12 12:52:51 nm4 Exp $
 
 From time to time, experimental features may be added to Exim.
 While a feature  is experimental, there  will be a  build-time
@@ -799,6 +799,9 @@ variables.
   draft, this header must be added at the top of the header
   list. Please see section 10 on how you can do this.
 
+  Note: in case of "Best-guess" (see below), the convention is
+  to put this string in a header called X-SPF-Guess: instead.
+
   $spf_result
   This contains the outcome of the SPF check in string form,
   one of pass, fail, softfail, none, neutral, err_perm or
@@ -808,6 +811,37 @@ variables.
   This contains a string that can be used in a SMTP response
   to the calling party. Useful for "fail".
 
+In addition to SPF, you can also perform checks for so-called
+"Best-guess".  Strictly speaking, "Best-guess" is not standard
+SPF, but it is supported by the same framework that enables SPF
+capability.  Refer to http://www.openspf.org/FAQ/Best_guess_record
+for a description of what it means.
+
+To access this feature, simply use the spf_guess condition in place
+of the spf one.  For example:
+
+/* -----------------
+deny message = $sender_host_address doesn't look trustworthy to me
+     spf_guess = fail
+--------------------- */
+
+In case you decide to reject messages based on this check, you
+should note that although it uses the same framework, "Best-guess"
+is NOT SPF, and therefore you should not mention SPF at all in your
+reject message.
+
+When the spf_guess condition has run, it sets up the same expansion
+variables as when spf condition is run, described above.
+
+Additionally, since Best-guess is not standarized, you may redefine
+what "Best-guess" means to you by redefining spf_guess variable in
+global config.  For example, the following:
+
+/* -----------------
+spf_guess = v=spf1 a/16 mx/16 ptr ?all
+--------------------- */
+
+would relax host matching rules to a broader network range.
 
 
 4. SRS (Sender Rewriting Scheme) Support
index e0f01694b96ce2f3a8be57a1a2cb3b3f54c81ec0..fcafc6b5812dfdb18cdb29eb644b5214ae0931d5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.81 2008/01/17 13:03:35 tom Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.82 2008/02/12 12:52:51 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -102,6 +102,7 @@ enum { ACLC_ACL,
 #endif
 #ifdef EXPERIMENTAL_SPF
        ACLC_SPF,
+       ACLC_SPF_GUESS,
 #endif
        ACLC_VERIFY };
 
@@ -165,6 +166,7 @@ static uschar *conditions[] = {
 #endif
 #ifdef EXPERIMENTAL_SPF
   US"spf",
+  US"spf_guess",
 #endif
   US"verify" };
 
@@ -300,6 +302,7 @@ static uschar cond_expand_at_top[] = {
 #endif
 #ifdef EXPERIMENTAL_SPF
   TRUE,    /* spf */
+  TRUE,    /* spf_guess */
 #endif
   TRUE     /* verify */
 };
@@ -363,6 +366,7 @@ static uschar cond_modifiers[] = {
 #endif
 #ifdef EXPERIMENTAL_SPF
   FALSE,   /* spf */
+  FALSE,   /* spf_guess */
 #endif
   FALSE    /* verify */
 };
@@ -547,6 +551,14 @@ static unsigned int cond_forbids[] = {
     (1<<ACL_WHERE_STARTTLS)|(1<<ACL_WHERE_VRFY)|
     (1<<ACL_WHERE_NOTSMTP)|
     (1<<ACL_WHERE_NOTSMTP_START),
+
+  (1<<ACL_WHERE_AUTH)|(1<<ACL_WHERE_CONNECT)|      /* spf_guess */
+    (1<<ACL_WHERE_HELO)|
+    (1<<ACL_WHERE_MAILAUTH)|
+    (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+    (1<<ACL_WHERE_STARTTLS)|(1<<ACL_WHERE_VRFY)|
+    (1<<ACL_WHERE_NOTSMTP)|
+    (1<<ACL_WHERE_NOTSMTP_START),
   #endif
 
   /* Certain types of verify are always allowed, so we let it through
@@ -3134,7 +3146,10 @@ for (; cb != NULL; cb = cb->next)
 
     #ifdef EXPERIMENTAL_SPF
     case ACLC_SPF:
-      rc = spf_process(&arg, sender_address);
+      rc = spf_process(&arg, sender_address, SPF_PROCESS_NORMAL);
+    break;
+    case ACLC_SPF_GUESS:
+      rc = spf_process(&arg, sender_address, SPF_PROCESS_GUESS);
     break;
     #endif
 
index beb72aa678470696e617dcc3fc874598c6ee3477..b2d0fb4aee9804da5b6b7bbb6ce66c6a74761ba4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/expand.c,v 1.92 2008/01/17 13:03:35 tom Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.93 2008/02/12 12:52:51 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -575,6 +575,7 @@ static var_entry var_table[] = {
   { "spam_score_int",      vtype_stringptr,   &spam_score_int },
 #endif
 #ifdef EXPERIMENTAL_SPF
+  { "spf_guess",           vtype_stringptr,   &spf_guess },
   { "spf_header_comment",  vtype_stringptr,   &spf_header_comment },
   { "spf_received",        vtype_stringptr,   &spf_received },
   { "spf_result",          vtype_stringptr,   &spf_result },
index e7efebffa519556a34915cb8785aa8441b89ae14..93f74910c77ffd45d1c0b9cbc18046b22f273e29 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.80 2008/01/17 13:03:35 tom Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.81 2008/02/12 12:52:51 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1136,6 +1136,7 @@ uschar *spam_score             = NULL;
 uschar *spam_score_int         = NULL;
 #endif
 #ifdef EXPERIMENTAL_SPF
+uschar *spf_guess              = US"v=spf1 a/24 mx/24 ptr ?all";
 uschar *spf_header_comment     = NULL;
 uschar *spf_received           = NULL;
 uschar *spf_result             = NULL;
index 4172c7355981b5704aa00904bb5784bd66afe801..ac425ed9812d5f4c9da9eb148dad1135ac909814 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.61 2008/01/17 13:03:35 tom Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.62 2008/02/12 12:52:51 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -705,6 +705,7 @@ extern uschar *spam_score;             /* the spam score (float) */
 extern uschar *spam_score_int;         /* spam_score * 10 (int) */
 #endif
 #ifdef EXPERIMENTAL_SPF
+extern uschar *spf_guess;              /* spf best-guess record */
 extern uschar *spf_header_comment;     /* spf header comment */
 extern uschar *spf_received;           /* Received-SPF: header */
 extern uschar *spf_result;             /* spf result in string form */
index 0a577f7db6290b7a68c377e4a1c9bad28fc5c21a..2e65cd970fa257332f228944bf560c33f74aaba0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.34 2008/01/17 13:03:35 tom Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.35 2008/02/12 12:52:51 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -356,6 +356,9 @@ static optionlist optionlist_config[] = {
   { "smtp_return_error_details",opt_bool,        &smtp_return_error_details },
 #ifdef WITH_CONTENT_SCAN
   { "spamd_address",            opt_stringptr,   &spamd_address },
+#endif
+#ifdef EXPERIMENTAL_SPF
+  { "spf_guess",                opt_stringptr,   &spf_guess },
 #endif
   { "split_spool_directory",    opt_bool,        &split_spool_directory },
   { "spool_directory",          opt_stringptr,   &spool_directory },
index 0d2316e2e88064ce2f284dc532e4e5c3e7e29288..532f814221bb2e00b49f11e55e3057966adedc68 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/spf.c,v 1.7 2007/05/17 19:55:10 tom Exp $ */
+/* $Cambridge: exim/src/src/spf.c,v 1.8 2008/02/12 12:52:51 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -73,7 +73,7 @@ int spf_init(uschar *spf_helo_domain, uschar *spf_remote_addr) {
    context (if any), retrieves the result, sets up expansion
    strings and evaluates the condition outcome. */
 
-int spf_process(uschar **listptr, uschar *spf_envelope_sender) {
+int spf_process(uschar **listptr, uschar *spf_envelope_sender, int action) {
   int sep = 0;
   uschar *list = *listptr;
   uschar *spf_result_id;
@@ -93,7 +93,10 @@ int spf_process(uschar **listptr, uschar *spf_envelope_sender) {
   }
 
   /* get SPF result */
-  SPF_request_query_mailfrom(spf_request, &spf_response);
+  if (action == SPF_PROCESS_FALLBACK)
+    SPF_request_query_fallback(spf_request, &spf_response, spf_guess);
+  else
+    SPF_request_query_mailfrom(spf_request, &spf_response);
 
   /* set up expansion items */
   spf_header_comment     = (uschar *)SPF_response_get_header_comment(spf_response);
@@ -106,6 +109,10 @@ int spf_process(uschar **listptr, uschar *spf_envelope_sender) {
   /* We got a result. Now see if we should return OK or FAIL for it */
   SPF_EVALUATE:
   debug_printf("SPF result is %s (%d)\n", SPF_strresult(rc), rc);
+
+  if (action == SPF_PROCESS_GUESS && (!strcmp (SPF_strresult(rc), "none")))
+    return spf_process(listptr, spf_envelope_sender, SPF_PROCESS_FALLBACK);
+
   while ((spf_result_id = string_nextinlist(&list, &sep,
                                      spf_result_id_buffer,
                                      sizeof(spf_result_id_buffer))) != NULL) {
index 3e014bdafe30ae5587e7d314633d900c3d0badb0..455fbbfd939c2da14a4c571f29c3f6c2652504a2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/spf.h,v 1.6 2005/06/27 15:28:45 tom Exp $ */
+/* $Cambridge: exim/src/src/spf.h,v 1.7 2008/02/12 12:52:51 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -26,6 +26,10 @@ typedef struct spf_result_id {
 
 /* prototypes */
 int spf_init(uschar *,uschar *);
-int spf_process(uschar **, uschar *);
+int spf_process(uschar **, uschar *, int);
+
+#define SPF_PROCESS_NORMAL  0
+#define SPF_PROCESS_GUESS   1
+#define SPF_PROCESS_FALLBACK    2
 
 #endif