Update of /cvsroot/tmda/tmda/bin
In directory usw-pr-cvs1:/tmp/cvs-serv9060/bin
Modified Files:
ChangeLog tmda-rfilter
Log Message:
Add support for the ``X-Primary-Address'' header in order to
help users of challenge/response systems like TMDA interact more
seamlessly.
Previously, when TMDA users interacted, there was no way for the user
to specify which address he prefers be "whitelisted" after he
successfully confirmed his first message. This problem was
exacerbated by use of 'dated' addresses, since you'd have to confirm
each of your messages over and over until the recipient stepped in and
manually added a "wildcard" entry for you.
We now support a header called ``X-Primary-Address'' which allows the
user to specify the address he prefers be whitelisted. A general name
was chosen for this header to encourage other C/R systems to adopt it.
The take advantage of this feature, you should configure your MUA to
add an X-Primary-Address: address field to your outgoing message. e.g,
X-Primary-Address: [EMAIL PROTECTED]
If you use tmda-sendmail or tmda-ofmipd to send your outgoing mail,
you can do this with an `ADDED_HEADERS_CLIENT' entry in your
~/.tmda/config.
Now, if an incoming message contains an ``X-Primary-Address'' header,
TMDA will CONFIRM_APPEND that address instead of the Return-Path address
when the message is confirmed.
TMDA will also check the address in ``X-Primary-Address'' against
FILTER_INCOMING along with the envelope sender, From and Reply-To.
To limit the potential for abuse where a sender would specify an
external address to get it whitelisted, TMDA will only honor
``X-Primary-Address'' if the address looks sufficiently similar to the
envelope sender address. If not, TMDA falls back on using the envelope
sender address instead. The necessary degree of closeness can be tuned
by setting the PRIMARY_ADDRESS_MATCH variable. The default setting is
to accept if the domains of the addresses match. This should be
flexible enough to cover most users while still greatly limiting
potential abuse.
Overall, this mechanism should reduce the amount of thinking and
planning ahead you need to do when sending mail to a new correspondent
who may or may not use a C/R system.
Thanks to Gre7g Luterman for this idea.
Index: ChangeLog
===================================================================
RCS file: /cvsroot/tmda/tmda/bin/ChangeLog,v
retrieving revision 1.240
retrieving revision 1.241
diff -u -r1.240 -r1.241
--- ChangeLog 9 Nov 2002 00:56:30 -0000 1.240
+++ ChangeLog 13 Nov 2002 01:56:53 -0000 1.241
@@ -1,3 +1,11 @@
+2002-11-12 Jason R. Mastaler <[EMAIL PROTECTED]>
+
+ * tmda-rfilter (verify_confirm_cookie): Append the address in
+ X-Primary-Address if the PRIMARY_ADDRESS_MATCH is close enough.
+
+ (main): Check the address in X-Primary-Address against
+ FILTER_INCOMING if the PRIMARY_ADDRESS_MATCH is close enough.
+
2002-11-08 Jason R. Mastaler <[EMAIL PROTECTED]>
* tmda-pending (main): Display Defaults.SUMMARY_HEADERS during
Index: tmda-rfilter
===================================================================
RCS file: /cvsroot/tmda/tmda/bin/tmda-rfilter,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -r1.71 -r1.72
--- tmda-rfilter 4 Nov 2002 19:10:59 -0000 1.71
+++ tmda-rfilter 13 Nov 2002 01:56:53 -0000 1.72
@@ -124,6 +124,7 @@
from cStringIO import StringIO
+from email.Utils import parseaddr, getaddresses
import email
import fileinput
import string
@@ -176,8 +177,7 @@
# Use Defaults.RECIPIENT_HEADER instead if set.
recipient_header = None
if Defaults.RECIPIENT_HEADER:
- recipient_header = email.Utils.parseaddr(msgin.get
- (Defaults.RECIPIENT_HEADER))[1]
+ recipient_header = parseaddr(msgin.get(Defaults.RECIPIENT_HEADER))[1]
envelope_recipient = (recipient_header or os.environ.get('RECIPIENT'))
if envelope_recipient == None:
raise Errors.MissingEnvironmentVariable('RECIPIENT')
@@ -248,8 +248,9 @@
fileinput.close()
break
-# Collect the message's Subject: for later use.
+# Collect some header values for later use.
subject = msgin.get('subject')
+x_primary_address = parseaddr(msgin.get('x-primary-address'))[1]
# The directory of pending messages.
pendingdir = os.path.join(Defaults.DATADIR, 'pending')
@@ -394,8 +395,7 @@
def release_pending(timestamp, pid, msg):
"""Release a confirmed message from the pending queue."""
# Remove Return-Path: to avoid duplicates.
- return_path = return_path = email.Utils.parseaddr(msg.get
- ('return-path'))[1]
+ return_path = return_path = parseaddr(msg.get('return-path'))[1]
del msg['return-path']
# Remove X-TMDA-Recipient:
recipient = msg.get('x-tmda-recipient')
@@ -458,13 +458,15 @@
send_cc(Defaults.CONFIRM_ACCEPT_CC)
if os.path.exists(confirmed_file):
msg = email.message_from_file(open(confirmed_file, 'r'))
- # Optionally append the envelope sender to a file
+ # Optionally append the sender's address to a file.
if Defaults.CONFIRM_APPEND:
- return_path = email.Utils.parseaddr(msg.get('return-path'))[1]
- if return_path is None:
+ confirm_append_addr = Util.confirm_append_address(
+ parseaddr(msg.get('x-primary-address'))[1],
+ parseaddr(msg.get('return-path'))[1])
+ if not confirm_append_addr:
raise IOError, \
confirmed_file + ' has no Return-Path header!'
- if Util.append_to_file(return_path,
+ if Util.append_to_file(confirm_append_addr,
Defaults.CONFIRM_APPEND) != 0:
logit('CONFIRM_APPEND ' + Defaults.CONFIRM_APPEND)
# Optionally generate a confirmation acceptance notice.
@@ -610,6 +612,9 @@
recipient_address = globals().get('recipient_address')
recipient_local, recipient_domain = recipient_address.split('@', 1)
envelope_sender = globals().get('envelope_sender')
+ x_primary_address = globals().get('x_primary_address')
+ confirm_append_address = Util.confirm_append_address(x_primary_address,
+ envelope_sender)
subject = globals().get('subject')
original_message_body = globals().get('orig_msgin_body_as_raw_string')
original_message_headers = globals().get('orig_msgin_headers_as_raw_string')
@@ -683,24 +688,26 @@
except IndexError:
# not a tagged address
pass
-
# The list of sender e-mail addresses comes from the envelope
- # sender, the "From:" header and the "Reply-To:" header.
+ # sender, the "From:" header, the "Reply-To:" header, and possibly
+ # the "X-Primary-Address" header.
sender_list = [envelope_sender]
- from_list = email.Utils.getaddresses(msgin.get_all('from', []))
- replyto_list = email.Utils.getaddresses(msgin.get_all('reply-to', []))
+ confirm_append_address = Util.confirm_append_address(x_primary_address,
+ envelope_sender)
+ if confirm_append_address and confirm_append_address != envelope_sender:
+ sender_list.append(confirm_append_address)
+ from_list = getaddresses(msgin.get_all('from', []))
+ replyto_list = getaddresses(msgin.get_all('reply-to', []))
for list in from_list, replyto_list:
for a in list:
emaddy = a[1]
sender_list.append(emaddy)
-
# Process confirmation messages first.
confirm_done_hdr = msgin.get('x-tmda-confirm-done')
if confirm_done_hdr:
verify_confirm_cookie(confirm_done_hdr, 'done')
if (cookie_type in Defaults.TAGS_CONFIRM) and cookie_value:
verify_confirm_cookie(cookie_value, 'accept')
-
# Parse the incoming filter file.
infilter = FilterParser.FilterParser()
infilter.read(Defaults.FILTER_INCOMING)
@@ -736,8 +743,6 @@
elif action == 'hold':
logit('%s (%s)' % ('HOLD', matching_line))
bouncegen('hold')
-
-
# The message didn't match the filter file, so check if it was
# sent to a 'tagged' address.
# Dated tag?
@@ -753,7 +758,6 @@
elif (cookie_type in map(lambda s: s.lower(), Defaults.TAGS_KEYWORD)) \
and cookie_value:
verify_keyword_cookie(cookie_value)
-
# If the message gets this far (i.e, was not sent to a tagged
# address and it didn't match the filter file), then we consult
# Defaults.ACTION_INCOMING.
_______________________________________
tmda-cvs mailing list
http://tmda.net/lists/listinfo/tmda-cvs