Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
pymilter
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
misc
pymilter
Commits
6048fe6e
Commit
6048fe6e
authored
17 years ago
by
Stuart Gathman
Browse files
Options
Downloads
Patches
Plain Diff
Remove explicit spf dependency.
parent
d2253848
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
Milter/dns.py
+62
-0
62 additions, 0 deletions
Milter/dns.py
Milter/dsn.py
+9
-5
9 additions, 5 deletions
Milter/dsn.py
with
71 additions
and
5 deletions
Milter/dns.py
0 → 100644
+
62
−
0
View file @
6048fe6e
# provide a higher level interface to pydns
import
DNS
from
DNS
import
DNSError
MAX_CNAME
=
10
def
DNSLookup
(
name
,
qtype
):
try
:
req
=
DNS
.
DnsRequest
(
name
,
qtype
=
qtype
)
resp
=
req
.
req
()
#resp.show()
# key k: ('wayforward.net', 'A'), value v
# FIXME: pydns returns AAAA RR as 16 byte binary string, but
# A RR as dotted quad. For consistency, this driver should
# return both as binary string.
return
[((
a
[
'
name
'
],
a
[
'
typename
'
]),
a
[
'
data
'
])
for
a
in
resp
.
answers
]
except
IOError
,
x
:
raise
DNSError
,
str
(
x
)
class
Session
(
object
):
"""
A Session object has a simple cache with no TTL that is valid
for a single
"
session
"
, for example an SMTP conversation.
"""
def
__init__
(
self
):
self
.
cache
=
{}
def
dns
(
self
,
name
,
qtype
,
cnames
=
None
):
"""
DNS query.
If the result is in cache, return that. Otherwise pull the
result from DNS, and cache ALL answers, so additional info
is available for further queries later.
CNAMEs are followed.
If there is no data, [] is returned.
pre: qtype in [
'
A
'
,
'
AAAA
'
,
'
MX
'
,
'
PTR
'
,
'
TXT
'
,
'
SPF
'
]
post: isinstance(__return__, types.ListType)
"""
result
=
self
.
cache
.
get
(
(
name
,
qtype
)
)
cname
=
None
if
not
result
:
safe2cache
=
query
.
SAFE2CACHE
for
k
,
v
in
DNSLookup
(
name
,
qtype
,
self
.
strict
):
if
k
==
(
name
,
'
CNAME
'
):
cname
=
v
if
(
qtype
,
k
[
1
])
in
safe2cache
:
self
.
cache
.
setdefault
(
k
,
[]).
append
(
v
)
result
=
self
.
cache
.
get
(
(
name
,
qtype
),
[])
if
not
result
and
cname
:
if
not
cnames
:
cnames
=
{}
elif
len
(
cnames
)
>=
MAX_CNAME
:
#return result # if too many == NX_DOMAIN
raise
DNSError
(
'
Length of CNAME chain exceeds %d
'
%
MAX_CNAME
)
cnames
[
name
]
=
cname
if
cname
in
cnames
:
raise
DNSError
,
'
CNAME loop
'
result
=
self
.
dns
(
cname
,
qtype
,
cnames
=
cnames
)
return
result
This diff is collapsed.
Click to expand it.
Milter/dsn.py
+
9
−
5
View file @
6048fe6e
...
...
@@ -5,6 +5,9 @@
# Send DSNs, do call back verification,
# and generate DSN messages from a template
# $Log$
# Revision 1.14 2007/03/03 18:19:40 customdesigned
# Handle DNS error sending DSN.
#
# Revision 1.13 2007/01/04 18:01:11 customdesigned
# Do plain CBV when template missing.
#
...
...
@@ -19,22 +22,22 @@
#
import
smtplib
import
spf
import
socket
from
email.Message
import
Message
import
Milter
import
time
import
dns
def
send_dsn
(
mailfrom
,
receiver
,
msg
=
None
,
timeout
=
600
):
def
send_dsn
(
mailfrom
,
receiver
,
msg
=
None
,
timeout
=
600
,
session
=
None
):
"""
Send DSN. If msg is None, do callback verification.
Mailfrom is original sender we are sending DSN or CBV to.
Receiver is the MTA sending the DSN.
Return None for success or (code,msg) for failure.
"""
user
,
domain
=
mailfrom
.
split
(
'
@
'
)
if
not
session
:
session
=
dns
.
Session
()
try
:
q
=
spf
.
query
(
None
,
None
,
None
)
mxlist
=
q
.
dns
(
domain
,
'
MX
'
)
except
spf
.
TempError
:
mxlist
=
session
.
dns
(
domain
,
'
MX
'
)
except
dns
.
DNSError
:
return
(
450
,
'
DNS Timeout: %s MX
'
%
domain
)
# temp error
if
not
mxlist
:
mxlist
=
(
0
,
domain
),
# fallback to A record when no MX
...
...
@@ -124,6 +127,7 @@ def create_msg(q,rcptlist,origmsg=None,template=None):
return
msg
if
__name__
==
'
__main__
'
:
import
spf
q
=
spf
.
query
(
'
192.168.9.50
'
,
'
SRS0=pmeHL=RH==stuart@example.com
'
,
'
red.example.com
'
,
receiver
=
'
mail.example.com
'
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment