spf-discuss
[Top] [All Lists]

Re: What to do about redirect= and NXDOMAIN?

2005-05-21 07:16:49
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Julian Mehnle wrote:
I think "redirect=" should have never been allowed to be used in
combination with real policy content in the same record.  A meaningful
alternative would be:

  "v=spf1 mx -exists:%{ir}.dnsbl.org include:example.com"

And, since we cannot declare "v=spf1 $SOME_POLICY redirect=..." to be
syntactically invalid, I think that's how your example should actually
be interpreted.

However, I'm unsure whether and how this massive inconsistency in the
current specification (i.e. returning "None" despite some policy already
having been evaluated) can be resolved without becoming significantly
backwards incompatible.

I think there is a solution:

Now, for reasons of consistency, my previous statement, that "redirect=
existent-domain-without-spf-record" returning "None" was perfectly fine,
must be incorrect. 

I still stand by that...

There should be no concept of a "partial policy".  If there is _some_
policy, the "None" result code should _not_ be returned.  Instead
"PermError" should be returned if the remaining policy (allegedly to
be found at "example.com") cannot be retrieved.

...so the tendency of never returning "None" when some policy has already 
been evaluated is right, I think.  But "PermError" is probably not be the 
best choice for the result of "v=spf1 ... redirect=domain-w/o-spf-record", 
either.

Perhaps in this special case, something other, but equivalent, to "None" 
should be returned, like, "Neutral"?  As per section 4.7 of the spec, 
"Neutral" is the default result when falling off the end of the record.  
This would also make "v=spf1 ... redirect=domain-w/o-spf-record" behave 
exactly like "v=spf1 ... include:domain-w/o-spf-record".

So this what I think we should do:

             | non-existent domain | domain w/o SPF record
  -----------+---------------------+-----------------------
   include:  | PermError (throw)   | None* (no match)
   redirect= | PermError*          | None / Neutral*

(* marks differences from the current specification.)

The left column currently only matches the behavior of "include:", while 
"redirect=" is indirectly (through 2.5.1, "None", and 4.3, "Initial 
Processing") defined to yield "None".  But, again, I think "include:" and 
"redirect=" should be made consistent in this regard.

The right column currently only matches the behavior of "redirect=", except 
for the case when combined with some policy mechanisms in the same record.  
"include:" is currently defined to yield "PermError".

The below patch only cares about the right (hopefully uncontroversial) 
column.  1) It makes "include:domain-w/o-spf-record" not throw "PermError" 
but simply not match instead, plus 2) it makes the special case
"... redirect=domain-w/o-spf-record" yield "Neutral" instead of "None".

I think these changes are very backwards compatible because 1) it just 
slightly relaxes the behavior of a special case of "include:", and 2) it 
returns "Neutral" instead of "None" in a very special case of "redirect=".

As for the left column, in order to make "include:" and "redirect=" 
consistent, we should either...
  * define "include:non-existent-domain" to not match (equivalent to
    "redirect="'s current result of "None" in that case), or
  * define "redirect=non-existent-domain" to yield "PermError" --
    best by defining check_host(non-existent-domain) == PermError.
This is known to be controversial and thus not included in the below patch.

- --- draft-schlitt-spf-classic-01.xml
+++ draft-schlitt-spf-classic-01+mehnle_include_redirect.xml
@@ -1087,10 +1087,10 @@
           <c>Neutral</c>
           <c>not match</c>
+          <c>None</c>
+          <c>not match</c>
           <c>TempError</c>
           <c>throw TempError</c>
           <c>PermError</c>
           <c>throw PermError</c>
- -          <c>None</c>
- -          <c>throw PermError</c>
         </texttable>
         <t>
@@ -1343,5 +1343,6 @@
         <t>
           The result of this new evaluation of check_host() is then
- -          considered the result of the current evaluation.
+          considered the result of the current evaluation.  See the
+          special case below for an exception.
         </t>
         <t>
@@ -1367,4 +1368,22 @@
         </t>
         <t>
+          Note: In the special case that the "redirect" modifier is
+          combined with policy mechanisms in the same record, when the
+          redirection is evaluated and yields a "None" result, the
+          overall result is "Neutral" instead of "None". It would be
+          misleading to return "None" even though some policy was found
+          and evaluated. For example:
+        </t>
+        <list>
+          <t>
+            v=spf1 a mx redirect=other.example.com
+          </t>
+        </list>
+        <t>
+          If neither the "a" nor the "mx" mechanism matched, and no
+          policy for other.example.com can be found, the overall result
+          is "Neutral".
+        </t>
+        <t>
           Note: In general, the domain "A" cannot reliably use a
           redirect to another domain "B" not under the same

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFCj0LSwL7PKlBZWjsRAkyCAKCcr2ihRn3pZA6julTcpxJIzahbUACcCw3w
zvKDw0Ttda6CwSBAohBSSdU=
=pYDg
-----END PGP SIGNATURE-----