[Pymilter] [PATCH] Accept DNS names in iniplist
Stuart D Gathman
stuart at bmsi.com
Thu Mar 27 22:33:43 EDT 2014
On Mar 26, Stuart D Gathman transmitted in part:
> On 03/25/2014 02:36 PM, David Caldwell wrote:
>>
>>> This is a good idea. The patch does not handle cidr, however, and
>>> I'm pretty sure from eyeballing it that it doesn't work for IP6 either.
>>> I'll polish it up and add it, however.
Here is my iteration. I kept dependencies to a minimum, and check the
list recursively. It would likely be faster to repeat the cidrmatch code and
use DNSLookup like you did (setting arec = 'A' or 'AAAA' depending on
whether ipaddr is IP6), but this way has minimal code and dependencies.
It handles IP6 and CIDR.
Index: utils.py
===================================================================
RCS file: /cvsroot/pymilter/pymilter/Milter/utils.py,v
retrieving revision 1.13
diff -u -r1.13 utils.py
--- utils.py 12 Mar 2013 01:46:08 -0000 1.13
+++ utils.py 28 Mar 2014 02:28:32 -0000
@@ -11,6 +11,7 @@
#import email.Utils
import rfc822
+dnsre = re.compile(r'^[a-z][-a-z\d.]+$', re.IGNORECASE)
PAT_IP4 = r'\.'.join([r'(?:\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])']*4)
ip4re = re.compile(PAT_IP4+'$')
ip6re = re.compile( '(?:%(hex4)s:){6}%(ls32)s$'
@@ -67,6 +68,12 @@
True
>>> iniplist('192.168.0.45',['192.168.0.*'])
True
+ >>> iniplist('4.2.2.2',['b.resolvers.Level3.net'])
+ True
+ >>> iniplist('2607:f8b0:4004:801::',['google.com/64'])
+ True
+ >>> iniplist('4.2.2.2',['nothing.example.com'])
+ False
>>> iniplist('2001:610:779:0:223:6cff:fe9a:9cf3',['127.0.0.1','172.20.1.0/24','2001:610:779::/48'])
True
>>> iniplist('2G01:610:779:0:223:6cff:fe9a:9cf3',['127.0.0.1','172.20.1.0/24','2001:610:779::/48'])
@@ -75,8 +82,10 @@
ValueError: Invalid ip syntax:2G01:610:779:0:223:6cff:fe9a:9cf3
"""
if ip4re.match(ipaddr):
+ fam = socket.AF_INET
ipnum = addr2bin(ipaddr)
elif ip6re.match(ipaddr):
+ fam = socket.AF_INET6
ipnum = bin2long6(inet_pton(ipaddr))
else:
raise ValueError('Invalid ip syntax:'+ipaddr)
@@ -96,6 +105,13 @@
n = 128
if cidr(bin2long6(inet_pton(p[0])),n,MASK6) ==
cidr(ipnum,n,MASK6):
return True
+ elif dnsre.match(p[0]):
+ try:
+ sfx = '/'.join(['']+p[1:])
+ addrlist = [r[4][0]+sfx for r in
socket.getaddrinfo(p[0],25,fam)]
+ if iniplist(ipaddr,addrlist):
+ return True
+ except socket.gaierror: pass
elif fnmatchcase(ipaddr,pat):
return True
return False
More information about the Pymilter
mailing list