At 07:47 PM 8/19/2005 -0400, John Leslie wrote:
David MacQuigg <dmquigg-clear(_at_)yahoo(_dot_)com> wrote:
Seems to me if CSV is going to standardize a set of result keywords, you
would want as many as there are distinct results. It is much easier to
combine two results into one action than parse an explanation string to
decide if a DNSError is a tempfail or some other error. I would split
'neutral' into 'none' and 'neutral', and split 'tempfail' into 'tempfail'
and 'error'.
I quite agree. "None" is a better description of the absence of records;
"Neutral" might lead to trying some service that advises for rare cases.
Similarly, the distinction between temporary errors which lead to retry
vs. permanent errors which are immediately reported to the user is well
established in eMail.
OK, I'm convinced this is getting complicated enough to split the module
into a "pure CSV" part and a wrapper that translates CSV results to SMTP
actions. I changed the name of the module to csv.py and the name of the
function to csa. Thus the call will be to csv.csa. There are several
places in the script where I wasn't sure if I should use CSV or CSA, so
edit as you please. My recommendation is to favor CSV, simply to avoid
dilution of the "trademark". We techies tend to overload the public with
too many subtle distinctions.
I've put in some awkward stubs for testing edge cases. If someone will
publish some broken records, I'll use those instead.
Here is the first page. The full module is at
http://purl.net/macquigg/email/python/csv.py To test it, fire up a Python
interpreter, import the module, and type the commands exactly as shown in
the examples.
# csv-0.4.py David MacQuigg (c) 8/20/05
# This code is open-source on the same terms as Python.
'''
Email authentication using CSV/CSA v.1 (draft-ietf-marid-csv-csa-02)
Not Implemented: Checking parent domains for subdomain authorization.
'''
# 0.4 Return results, not actions.
# Change module name to csv, function name to csa.
# 0.3 Handle weight=3 records.
# 0.2 Ignore SRV records with version numbers other than 1.
...
def csa(IP, helo):
'''
Runs a CSV/CSA test on the HELO name.
Returns ( result, SMTP_reply )
result = (
'pass', # IP passes the test
'fail', # IP fails the test / error on sender side
'neutral', # test completed with no definite result
'none', # no CSV records found
'tempfail', # try again in a few minutes
'error' # on receiver side, e.g. "No route to nameservers",
# "No working nameservers", etc.
)
SMTP_reply = ( SMTP_code, Xcode, explanation )
(550, '5.7.1', 'Sender not authorized')
SMTP_code: SMTP Reply Code per RFC-2821
Xcode: Enhanced Mail System Status Code per RFC-3463
Examples:
csa('168.61.5.27', 'harry.mail-abuse.org')
('pass', (250, '?.?.?', 'Sender CSV OK'))
csa('192.168.0.1', 'harry.mail-abuse.org')
('fail', (550, '5.7.1', \
"'192.168.0.1' not authorized by 'harry.mail-abuse.org'"))
csa('192.168.0.1', 'yahoo.com')
('none', (550, '?.?.?', "No CSV1 record for '_client._smtp.yahoo.com'."))
'''
Note: Other possible actions are 'CONTINUE' and 'DISCARD'. CONTINUE is
used when the result is inconclusive, and there are other methods to be
tried that are not yet integrated into this script. DISCARD is used for
known spammers. It means REJECT with no SMTP_reply - not the way I would
do it, but some admins want it, and Sendmail offers it.
"CONTINUE" is generally appropriate for "none" and "neutral". I don't
think CSV offers enough basis for distinguishing "ERROR" from "DISCARD",
though an individual reputation service (under DNA) might choose to.
I'll keep all this in the wrapper layer, which mail system admins can edit
as they like.
--
Dave
************************************************************ *
* David MacQuigg, PhD email: david_macquigg at yahoo.com * *
* IC Design Engineer phone: USA 520-721-4583 * * *
* Analog Design Methodologies * * *
* 9320 East Mikelyn Lane * * *
* VRS Consulting, P.C. Tucson, Arizona 85710 *
************************************************************ *