spf-discuss
[Top] [All Lists]

Re: Should SPF be Frozen or Extensible? (XML insights)

2004-05-31 08:00:18
On Mon, May 31, 2004 at 02:15:41AM -0700, Greg Connor wrote:
| Suppose the domain owner wants to say, "Use ptr and mx, and use domain keys 
| if available.  If not available, return unknown.  If no match to ptr, mx, 
| or domainkeys, return fail."
| 
| Sample extended record (current SPF treats this as an error)
| 
|  v=spf1 +ptr +mx +domainkeys -all
| 
| 0. Current SPF method:
| 
|  v=spf1 +ptr +mx ?all
|  v=spf2 +ptr +mx +domainkeys -all
| 
| 1. Add if/then syntax to the language (I doubt anyone would like this :)
| 
| 2. Use modifiers to say what to do in case of unknown mechanisms.
| 
|  v=spf1 +ptr +mx unsupported=? +domainkeys -all
| 
| The modifier "unsupported" tells what action to be taken when an unknown
| feature is encountered. That action will probably be one of:
|  unsupported=?  Stop processing and return "unknown" ("neutral")
|  unsupported=-  Stop processing and return "Fail"
|  unsupported=+  Stop processing and return "Pass" (pretty unlikely ;)
|  unsupported=abort  Stop processing and return error result (current
| behavior)
|  unsupported=continue  Ignore the unknown keyword and resume with the
| next step
|  unsupported=break  Stop processing the current record, but if we were in 
| an include: or redirect= then continue with the previous record

actually, the current behaviour is to stop processing and
return "unknown", rather than "error".

"unknown" and "error" should really be named "permfail" and
"tempfail".

"unknown/permfail" is semantically identical to neutral/none.

Of the alternatives you identified, 

|  unsupported=?  Stop processing and return "unknown" ("neutral")

this is the standard behaviour now.

|  unsupported=-  Stop processing and return "Fail"

if this were a desired semantic, why wouldn't a domain just
leave out the mechanism knowing that it was not widely supported?

|  unsupported=+  Stop processing and return "Pass" (pretty unlikely ;)

if this were a desired semantic, a domain should just leave
out the mechanism and do a +all.

|  unsupported=abort  Stop processing and return error result (current
| behavior)

this is close enough to the standard behaviour with
"unknown" that it should be classed under the first case.
The differences have mostly to do with the behaviour under
"include".

|  unsupported=continue  Ignore the unknown keyword and resume with the
| next step

this would be desirable, and reflects a set-theoretic rather
than procedural approach.  but again, why wouldn't a domain
just leave out the generally unrecognized unknown keyword?

|  unsupported=break  Stop processing the current record, but if we were in 
| an include: or redirect= then continue with the previous record

this would also be desirable.  adding features like these
would move use closer to being a fuller-featured language.

|  mydomain.com: v=spf1 +a +ptr include:comcast.net include:earthlink.net 
| -all
|  comcast.net: v=spf1 +a +ptr -all
|  earthlink.net: v=spf1 +a +ptr -all
| 
| Now, let's say what I *really* want is to return "unknown" (neutral) for
| Comcast, since I have some users, but there are also a lot of forgeries
| coming from there. If Comcast says it is a PASS, maybe I really want to
| interpret that as an unknown. In other words, I am going to (include,
| redirect, whatever) to comcast, and I'm fishing for a + or ? which I will
| treat as a ?, and if I get a - or error I will move to the next fork.

doesn't this do it?

  v=spf1 +a +ptr ?include:comcast.net include:earthlink.net -all

do you really want a ? from the include to cause a match on include:comcast.net?

either way, i think the possibility for fine-tuning lies
within this table:

      included    include
      query       mechanism      SPF
      result      result         processing
      -------- -- -------------- -------------------------------------
      pass     => match,         return the prefix value for "include"
      fail     => no match,      continue processing
      softfail => no match,      continue processing
      neutral  => no match,      continue processing
      error    => throw error,   abort processing, return error
      unknown  => throw unknown, abort processing, return unknown
      none     => throw unknown, abort processing, return unknown