1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
# $Log$
# Revision 1.1.1.1 2005/06/03 04:13:18 customdesigned
# Initial import
#
# Revision 1.1.1.1 2004/03/19 05:23:13 stuart
# Import to CVS
#
#
# AUTHOR
# Shevek
# CPAN ID: SHEVEK
# cpan@anarres.org
# http://www.anarres.org/projects/
#
# Translated to Python by stuart@bmsi.com
# http://bmsi.com/python/milter.html
#
# Portions Copyright (c) 2004 Shevek. All rights reserved.
# Portions Copyright (c) 2004 Business Management Systems. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Python itself.
import SRS
from .Base import Base
class Shortcut(Base):
"""SRS.Shortcut - A shortcutting Sender Rewriting Scheme
SYNOPSIS
import SRS.Shortcut
srs = SRS.Shortcut(...)
DESCRIPTION
WARNING: Using the simple Shortcut strategy is a very bad idea. Use the
Guarded strategy instead. The weakness in the Shortcut strategy is
documented at http://www.anarres.org/projects/srs/
See Mail::SRS for details of the standard SRS subclass interface.
This module provides the methods compile() and parse(). It operates
without store, and shortcuts around all middleman resenders."""
def compile(self,sendhost,senduser,srshost=None):
senduser,m = self.srs0re.subn('',senduser,1)
if m:
# This duplicates effort in Guarded.pm but makes this file work
# standalone.
# We just do the split because this was hashed with someone
# else's secret key and we can't check it.
# hash, timestamp, host, user
undef,undef,sendhost,senduser = senduser.split(SRS.SRSSEP,3)
# We should do a sanity check. After all, it might NOT be
# an SRS address, unlikely though that is. We are in the
# presence of malicious agents. However, this code is
# never reached if the Guarded subclass is used.
else:
senduser,m = self.srs1re.subn('',senduser,1)
if m:
# This should never be hit in practice. It would be bad.
# Introduce compatibility with the guarded format?
# SRSHOST, hash, timestamp, host, user
sendhost,senduser = senduser.split(SRS.SRSSEP,5)[-2:]
timestamp = self.timestamp_create()
hash = self.hash_create(timestamp.encode(), sendhost.encode(), senduser.encode())
if sendhost == srshost:
sendhost = ''
# Note that there are 5 fields here and that sendhost may
# not contain a valid separator. Therefore, we do not need to
# escape separators anywhere in order to reverse this
# transformation.
return SRS.SRS0TAG + self.separator + \
SRS.SRSSEP.join((hash.decode(),timestamp,sendhost,senduser))
def parse(self,user,srshost=None):
user,m = self.srs0re.subn('',user,1)
# We should deal with SRS1 addresses here, just in case?
assert m, "Reverse address does not match %s." % self.srs0re.pattern
# The 4 here matches the number of fields we encoded above. If
# there are more separators, then they belong in senduser anyway.
hash,timestamp,sendhost,senduser = user.split(SRS.SRSSEP,3)[-4:]
if not sendhost and srshost:
sendhost = srshost
# Again, this must match as above.
assert self.hash_verify(hash.encode(),timestamp.encode(),sendhost.encode(),senduser.encode()), "Invalid hash"
assert self.timestamp_check(timestamp), "Invalid timestamp"
return sendhost,senduser
|